__author__ = 'aherman'

from jinja2 import Environment, PackageLoader
import os
import packagingException as pe


class TemplateParemeters(object):
    def __init__(self, application, debug, memcached, folders, java, jmx, log, profiling, http, docker, deploy):
        self.application = application
        self.debug = debug
        self.memcached = memcached
        self.folders = folders
        self.java = java
        self.jmx = jmx
        self.log = log
        self.profiling = profiling
        self.http = http
        self.docker = docker
        self.deploy = deploy


def generateStartScript(applicationConfig):
    templateParemeters = _createTemplateParemeters(applicationConfig)

    binFolder = applicationConfig.assemblyHelper.binFolder
    startPath = binFolder + "/start.sh"

    if not os.path.exists(binFolder):
        os.makedirs(binFolder)
    elif not os.path.isdir(binFolder):
        raise pe.PackagingException("Not folder: {0}".format(binFolder))

    _generate(startPath, "start.sh.jinja", templateParemeters)

def generateDeployScripts(applicationConfig):
    templateParemeters = _createTemplateParemeters(applicationConfig)

    binFolder = applicationConfig.assemblyHelper.binFolder
    etcFolder = applicationConfig.assemblyHelper.etcFolder
    startPath = binFolder + "/start.sh"
    logrotatePath = applicationConfig.assemblyHelper.etcFolder + "/logrotate"

    if not os.path.exists(binFolder):
        os.makedirs(binFolder)
    elif not os.path.isdir(binFolder):
        raise pe.PackagingException("Not folder: {0}".format(binFolder))

    if not os.path.exists(etcFolder):
        os.makedirs(etcFolder)
    elif not os.path.isdir(etcFolder):
        raise pe.PackagingException("Not folder: {0}".format(etcFolder))

    _generate(startPath, "deploy/start.sh.jinja", templateParemeters)
    _generate(logrotatePath, "deploy/logrotate.jinja", templateParemeters)


def generateDevelopmentScripts(applicationConfig):
    templateParemeters = _createTemplateParemeters(applicationConfig)
    assemblyRoot = applicationConfig.assemblyHelper.assemblyRoot
    _generate(assemblyRoot + "/start.sh", "development.start.sh.jinja", templateParemeters)
    _generate(assemblyRoot + "/restart.sh", "development.restart.sh.jinja", templateParemeters)
    _generate(assemblyRoot + "/stop.sh", "development.stop.sh.jinja", templateParemeters)
    _generate(assemblyRoot + "/r.sh", "development.r.sh.jinja", templateParemeters)


def generateDebianScripts(applicationConfig):
    templateParemeters = _createTemplateParemeters(applicationConfig)

    postinstPath = applicationConfig.assemblyHelper.getPostinsFile(applicationConfig.packageName)
    _generate(postinstPath, "postinst.jinja", templateParemeters)

    postrmPath = applicationConfig.assemblyHelper.getPostrmFile(applicationConfig.packageName)
    _generate(postrmPath, "postrm.jinja", templateParemeters)

    if applicationConfig.initdConfig.ubic:
        initDPath = applicationConfig.assemblyHelper.getInitFile(applicationConfig.packageName)
        _generate(initDPath, "ubic/init.d.jinja", templateParemeters)

        logrotatePath = applicationConfig.assemblyHelper.getLogrotateFile(applicationConfig.packageName)
        _generate(logrotatePath, "ubic/logrotate.jinja", templateParemeters)

        ubicPath = applicationConfig.assemblyHelper.getUbicFile(
            applicationConfig.packageName,
            "{0}-{1}".format(applicationConfig.project, applicationConfig.module)
        )
        os.makedirs(os.path.dirname(ubicPath))
        print "Ubic: ", ubicPath
        _generate(ubicPath, "ubic/ubic.jinja", templateParemeters)
    elif applicationConfig.initdConfig.upstart:
        initDPath = applicationConfig.assemblyHelper.getInitFile(applicationConfig.packageName)
        _generate(initDPath, "upstart/init.d.jinja", templateParemeters)

        logrotatePath = applicationConfig.assemblyHelper.getLogrotateFile(applicationConfig.packageName)
        _generate(logrotatePath, "upstart/logrotate.jinja", templateParemeters)
    else:
        # oldstyle is default
        initDPath = applicationConfig.assemblyHelper.getInitFile(applicationConfig.packageName)
        _generate(initDPath, "oldstyle/init.d.jinja", templateParemeters)

        logrotatePath = applicationConfig.assemblyHelper.getLogrotateFile(applicationConfig.packageName)
        _generate(logrotatePath, "oldstyle/logrotate.jinja", templateParemeters)


def generateQloudScripts(applicationConfig):
    templateParemeters = _createTemplateParemeters(applicationConfig)

    initPath = applicationConfig.assemblyHelper.binFolder + "/init_and_start.sh"
    _generate(initPath, "qloud/init_and_start.sh.jinja", templateParemeters)

    dockerfilePath = applicationConfig.assemblyHelper.assemblyRoot + "/Dockerfile"
    _generate(dockerfilePath, "qloud/Dockerfile.jinja", templateParemeters)

    citJsonFilePath = applicationConfig.assemblyHelper.assemblyRoot + "/cit.update-env.json"
    _generate(citJsonFilePath, "qloud/cit.update-env.json.jinja", templateParemeters)

    citJsonFilePath = applicationConfig.assemblyHelper.assemblyRoot + "/cit.featurebranch.json"
    _generate(citJsonFilePath, "qloud/cit.featurebranch.json.jinja", templateParemeters)


def _createTemplateParemeters(applicationConfig):
    folders = {
        "bin": applicationConfig.folderHelper.binFolder,
        "etc": applicationConfig.folderHelper.etcFolder,
        "data": applicationConfig.folderHelper.dataFolder,
        "lib": applicationConfig.folderHelper.libFolder,
        "temp": applicationConfig.folderHelper.tempFolder,
        "logFile": applicationConfig.folderHelper.logFile,
        "logFolder": applicationConfig.folderHelper.logFolder,
        "logPath": applicationConfig.logFiles[0],
        "logPaths": applicationConfig.logFiles,
        "pidPath": applicationConfig.folderHelper.pidPath,
        "pidFolder": applicationConfig.folderHelper.pidFolder,
        "hprofFolder": applicationConfig.folderHelper.hprofFolder
    }

    createFolders = []
    folders["create"] = createFolders
    if applicationConfig.foldersConfig is not None:
        if applicationConfig.foldersConfig.other is not None:
            for path, value in applicationConfig.foldersConfig.other.iteritems():
                if "create" in value and value["create"]:
                    createFolders.append(path)

    log = {
        "folder": applicationConfig.folderHelper.logFolder,
        "file": applicationConfig.folderHelper.logFile,
        "gcLogFileName": applicationConfig.folderHelper.gcLogFile,
        "shLogFileName": applicationConfig.folderHelper.shLogFile,
        "configFileName": applicationConfig.loggingConfig.configFile,
        "redirectOutput": applicationConfig.loggingConfig.redirectOutput,
    }

    initFileName = applicationConfig.packageName
    if applicationConfig.initdConfig.options:
        if applicationConfig.initdConfig.options.scriptName:
            initFileName = applicationConfig.initdConfig.options.scriptName

    application = {
        "project": applicationConfig.project,
        "module": applicationConfig.module,
        "version": applicationConfig.version,
        "repositoryRevision": applicationConfig.repositoryRevision,
        "repositoryUrl": applicationConfig.repositoryUrl,
        "buildDate": applicationConfig.buildDate,
        "packageName": applicationConfig.packageName,
        "initFileName": initFileName,
    }
    if applicationConfig.pingDisableSleep is not None:
        application["ping_disable_sleep"] = applicationConfig.pingDisableSleep

    java = {
        "mainClass": applicationConfig.javaConfig.mainClass,
        "version": applicationConfig.javaConfig.version,
        "xms": applicationConfig.javaConfig.xms,
        "xmx": applicationConfig.javaConfig.xmx,
        "options": applicationConfig.javaConfig.options,
        "useG1GC": applicationConfig.javaConfig.useG1GC
    }

    jmx = {}
    if applicationConfig.monitoringConfig is not None:
        jmx["enabled"] = applicationConfig.monitoringConfig.jmxMonitoringConfig.enabled
        jmx["port"] = applicationConfig.monitoringConfig.jmxMonitoringConfig.port

    debug = {}
    if applicationConfig.debugConfig is not None:
        debug["enabled"] = applicationConfig.debugConfig.enabled
        debug["port"] = applicationConfig.debugConfig.port

    memcached = {}
    if applicationConfig.memcachedConfig is not None:
        memcached["enabled"] = "true"
        memcached["flush_on_restart"] = applicationConfig.memcachedConfig.flush_on_restart

    profiling = {}
    if applicationConfig.profilingConfig is not None:
        profiling["enabled"] = applicationConfig.profilingConfig.enabled
        profiling["agentPath"] = applicationConfig.profilingConfig.agentPath
        profiling["options"] = applicationConfig.profilingConfig.getOptionsAsString()

    http = {}
    if applicationConfig.httpConfig is not None:
        http["port"] = applicationConfig.httpConfig.port
        http["monitoringPort"] = applicationConfig.httpConfig.monitoringPort
        http["pingPort"] = applicationConfig.httpConfig.pingPort

    docker = {}
    if applicationConfig.dockerConfig is not None:
        docker["image"] = applicationConfig.dockerConfig.image

    deploy = {}
    deploy["mode"] = applicationConfig.deployMode
    return TemplateParemeters(application, debug, memcached, folders, java, jmx, log, profiling, http, docker, deploy)


def _generate(filePath, templateName, templateParemeters):
    env = Environment(loader=PackageLoader("packagingtools", "templates"))
    optionsTemplate = env.get_template(templateName)
    # print optionsTemplate.render(folders=templateParemeters.folders,
    #                              log=templateParemeters.log,
    #                              application=templateParemeters.application,
    #                              java=templateParemeters.java,
    #                              jmx=templateParemeters.jmx,
    #                              debug=templateParemeters.debug,
    #                              memcached=templateParameters.memcached,
    #                              profiling=templateParemeters.profiling)
    templateStream = optionsTemplate.stream(folders=templateParemeters.folders,
                                            log=templateParemeters.log,
                                            application=templateParemeters.application,
                                            java=templateParemeters.java,
                                            jmx=templateParemeters.jmx,
                                            debug=templateParemeters.debug,
                                            memcached=templateParemeters.memcached,
                                            profiling=templateParemeters.profiling,
                                            http=templateParemeters.http,
                                            docker=templateParemeters.docker,
                                            deploy=templateParemeters.deploy)
    templateStream.dump(filePath)
