#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import print_function, unicode_literals # We require Python 2.6 or later
from string import Template
import random
import string
import os
import sys
import argparse
import subprocess
import shutil
from io import open

if sys.version_info[:3][0] == 2:
    import ConfigParser as ConfigParser
    import StringIO as StringIO

if sys.version_info[:3][0] == 3:
    import configparser as ConfigParser
    import io as StringIO

base_dir = os.path.dirname(__file__)
config_dir = os.path.join(base_dir, "config")
templates_dir = os.path.join(base_dir, "templates")

def prep_conf_dir(root, name):
    absolute_path = os.path.join(root, name)
    if not os.path.exists(absolute_path):
        os.makedirs(absolute_path)
    return absolute_path

def render(src, dest, **kw):
    if not os.path.exists(os.path.dirname(dest)):
        os.makedirs(os.path.dirname(dest))
    t = Template(open(src, 'r').read())
    with open(dest, 'w') as f:
        f.write(t.substitute(**kw))
    os.chmod(dest, 0755)
    print("Generated configuration file: %s" % dest)

def delfile(src):
    if os.path.isfile(src):
        try:
            os.remove(src)
            print("Clearing the configuration file: %s" % src)
        except:
            pass
    elif os.path.isdir(src):
        for item in os.listdir(src):
            itemsrc=os.path.join(src,item)
            delfile(itemsrc)

parser = argparse.ArgumentParser()
parser.add_argument('--conf', dest='cfgfile', default=base_dir+'/board.cfg',type=str,help="the path of Board configuration file")
args = parser.parse_args()

delfile(config_dir)

FNULL = open(os.devnull, 'w')

#Read Configurations
conf = StringIO.StringIO()
conf.write("[configuration]\n")
conf.write(open(args.cfgfile).read())
conf.seek(0, os.SEEK_SET)
rcp = ConfigParser.RawConfigParser()
rcp.readfp(conf)

hostname = rcp.get("configuration", "hostname")
api_server_port = rcp.get("configuration", "api_server_port")
db_password = rcp.get("configuration", "db_password")
kube_master_ip = rcp.get("configuration", "kube_master_ip")
kube_master_port = rcp.get("configuration", "kube_master_port")
board_admin_password = rcp.get("configuration", "board_admin_password")
token_cache_expire_seconds = rcp.get("configuration", "token_cache_expire_seconds")
token_expire_seconds = rcp.get("configuration", "token_expire_seconds")
registry_ip = rcp.get("configuration", "registry_ip")
registry_port = rcp.get("configuration", "registry_port")

auth_mode = rcp.get("configuration", "auth_mode")
verification_url = rcp.get("configuration", "verification_url")
redirection_url = rcp.get("configuration", "redirection_url")

elaseticsearch_memory_in_megabytes = rcp.get("configuration", "elaseticsearch_memory_in_megabytes")

gogits_host_ip = rcp.get("configuration", "gogits_host_ip")
gogits_host_port = rcp.get("configuration", "gogits_host_port")
gogits_ssh_port = rcp.get("configuration", "gogits_ssh_port")

jenkins_host_ip = rcp.get("configuration", "jenkins_host_ip")
jenkins_host_port = rcp.get("configuration", "jenkins_host_port")
jenkins_node_ip = rcp.get("configuration", "jenkins_node_ip")
jenkins_node_ssh_port = rcp.get("configuration", "jenkins_node_ssh_port")
jenkins_node_username = rcp.get("configuration", "jenkins_node_username")
jenkins_node_password = rcp.get("configuration", "jenkins_node_password")
jenkins_node_volume = rcp.get("configuration", "jenkins_node_volume")
jenkins_execution_mode = rcp.get("configuration", "jenkins_execution_mode")

kvm_registry_size = rcp.get("configuration", "kvm_registry_size")
kvm_registry_port = rcp.get("configuration", "kvm_registry_port")
kvm_toolkits_path = rcp.get("configuration", "kvm_toolkits_path")

###email configuration
email_identity = rcp.get("configuration", "email_identity")
email_host = rcp.get("configuration", "email_server")
email_port = rcp.get("configuration", "email_server_port")
email_usr = rcp.get("configuration", "email_username")
email_pwd = rcp.get("configuration", "email_password")
email_from = rcp.get("configuration", "email_from")
email_ssl = rcp.get("configuration", "email_ssl")
########

audit_debug = rcp.get("configuration", "audit_debug")

###ldap configuration
ldap_url = rcp.get("configuration", "ldap_url")
# this two options are either both set or unset
if rcp.has_option("configuration", "ldap_searchdn"):
    ldap_searchdn = rcp.get("configuration", "ldap_searchdn")
    ldap_search_pwd = rcp.get("configuration", "ldap_search_pwd")
else:
    ldap_searchdn = ""
    ldap_search_pwd = ""
ldap_basedn = rcp.get("configuration", "ldap_basedn")
# ldap_filter is null by default
if rcp.has_option("configuration", "ldap_filter"):
    ldap_filter = rcp.get("configuration", "ldap_filter")
else:
    ldap_filter = ""
ldap_uid = rcp.get("configuration", "ldap_uid")
ldap_scope = rcp.get("configuration", "ldap_scope")
ldap_timeout = rcp.get("configuration", "ldap_timeout")


########

#Setting Directory
apiserver_config_dir = os.path.join(config_dir,"apiserver")
if not os.path.exists(apiserver_config_dir):
    os.makedirs(os.path.join(config_dir, "apiserver"))
apiserver_env= os.path.join(config_dir, "apiserver", "env")
if not os.path.exists(os.path.join(apiserver_config_dir, "kvmregistry")):
    os.makedirs(os.path.join(apiserver_config_dir, "kvmregistry"))
apiserver_kvm = os.path.join(apiserver_config_dir, "kvmregistry")


tokenserver_config_dir = os.path.join(config_dir,"tokenserver")
if not os.path.exists(tokenserver_config_dir):
    os.makedirs(os.path.join(config_dir, "tokenserver"))
tokenserver_env = os.path.join(config_dir, "tokenserver", "env")

collector_config_dir = os.path.join(config_dir,"collector")
if not os.path.exists(collector_config_dir):
    os.makedirs(os.path.join(config_dir, "collector"))
collector_conf_env = os.path.join(config_dir, "collector", "env")

db_config_dir = os.path.join(config_dir, "db")
if not os.path.exists(db_config_dir):
    os.makedirs(os.path.join(config_dir, "db"))
db_conf_env = os.path.join(config_dir, "db", "env")

proxy_conf = os.path.join(config_dir, "proxy", "nginx.conf")
proxy_config_dir = os.path.join(config_dir, "proxy")
if not os.path.exists(proxy_config_dir):
    os.makedirs(os.path.join(config_dir, "proxy"))

jenkins_config_dir = os.path.join(config_dir, "jenkins")
if not os.path.exists(jenkins_config_dir):
    os.makedirs(os.path.join(config_dir, "jenkins"))
jenkins_env = os.path.join(config_dir, "jenkins", "env")

gogits_config_dir = os.path.join(config_dir, "gogits")
if not os.path.exists(gogits_config_dir):
    os.makedirs(os.path.join(config_dir, "gogits"))
gogits_conf = os.path.join(config_dir, "gogits", "conf", "app.ini")

grafana_config_dir = os.path.join(config_dir, "grafana")
if not os.path.exists(grafana_config_dir):
    os.makedirs(os.path.join(config_dir, "grafana"))
grafana_k8s_ds = os.path.join(grafana_config_dir, "kubernetes-datasource.json")
grafana_graphite_ds = os.path.join(grafana_config_dir, "graphite-datasource.json")
grafana_dashboard = os.path.join(grafana_config_dir, "kubernetes-dashboard.json")
grafana_k8s = os.path.join(grafana_config_dir, "kubernetes.json")
grafana_notifications = os.path.join(grafana_config_dir, "notifications.json")

elasticsearch_config_dir = os.path.join(config_dir, "elasticsearch")
if not os.path.exists(elasticsearch_config_dir):
    os.makedirs(elasticsearch_config_dir)
elasticsearch_env = os.path.join(config_dir, "elasticsearch", "env")

kibana_config_dir = os.path.join(config_dir, "kibana")

#Render Configure File
render(os.path.join(templates_dir, "apiserver", "env"),
        apiserver_env,
        hostname=hostname,
        api_server_port=api_server_port,
        db_password=db_password,
        token_cache_expire_seconds=token_cache_expire_seconds,
        board_admin_password=board_admin_password,
        kube_master_ip=kube_master_ip,
        kube_master_port=kube_master_port,
        registry_ip=registry_ip,
        registry_port=registry_port,
        auth_mode=auth_mode,
        email_host=email_host,
        email_port=email_port,
        email_usr=email_usr,
        email_pwd=email_pwd,
        email_ssl=email_ssl,
        email_from=email_from,
        email_identity=email_identity,
        audit_debug=audit_debug,
        ldap_url=ldap_url,
        ldap_searchdn =ldap_searchdn, 
        ldap_search_pwd =ldap_search_pwd,
        ldap_basedn=ldap_basedn,
        ldap_filter=ldap_filter,
        ldap_uid=ldap_uid,
        ldap_scope=ldap_scope,
        ldap_timeout=ldap_timeout,
        verification_url=verification_url,
        redirection_url=redirection_url,
        gogits_host_ip=gogits_host_ip,
        gogits_host_port=gogits_host_port,
        gogits_ssh_port=gogits_ssh_port,
        jenkins_host_ip=jenkins_host_ip,
        jenkins_host_port=jenkins_host_port,
        jenkins_node_ip=jenkins_node_ip,
        jenkins_node_username=jenkins_node_username,
        jenkins_node_password=jenkins_node_password,
        jenkins_node_ssh_port=jenkins_node_ssh_port,
        jenkins_node_volume=jenkins_node_volume,
        jenkins_execution_mode=jenkins_execution_mode,
        kvm_registry_size=kvm_registry_size,
        kvm_registry_port=kvm_registry_port,
        kvm_toolkits_path=kvm_toolkits_path)


if os.path.exists(os.path.join(apiserver_config_dir, "kvm")):
    shutil.rmtree(os.path.join(apiserver_config_dir, "kvm"))
shutil.copytree(os.path.join(templates_dir, "apiserver", "kvm"), os.path.join(apiserver_config_dir, "kvm"))

if os.path.exists(os.path.join(apiserver_config_dir, "kvmregistry")):
    shutil.rmtree(os.path.join(apiserver_config_dir, "kvmregistry"))

if jenkins_execution_mode != "single":
    subprocess.call("docker run --rm -v `pwd`/templates/apiserver/kvmregistry:/go/src -w=/go/src golang:1.9.6 go build -o kvmregistry", shell=True)
    os.mkdir(os.path.join(apiserver_config_dir, "kvmregistry"))
    shutil.copyfile(os.path.join(templates_dir, "apiserver", "kvmregistry", "kvmregistry"), os.path.join(apiserver_config_dir, "kvmregistry", "kvmregistry"))
    shutil.copyfile(os.path.join(templates_dir, "apiserver", "kvmregistry", "affinity.ini"), os.path.join(apiserver_config_dir, "kvmregistry", "affinity.ini"))
    shutil.copyfile(os.path.join(templates_dir, "apiserver", "kvmregistry", "register.sh"), os.path.join(apiserver_config_dir, "kvmregistry", "register.sh"))
    shutil.copyfile(os.path.join(templates_dir, "apiserver", "kvmregistry", "release.sh"), os.path.join(apiserver_config_dir, "kvmregistry", "release.sh"))

render(os.path.join(templates_dir, "tokenserver", "env"),
        tokenserver_env,
        token_expire_seconds=token_expire_seconds)

render(os.path.join(templates_dir, "collector", "env"),
        collector_conf_env,
        kube_master_ip=kube_master_ip,
        kube_master_port=kube_master_port,
        db_password=db_password)

render(os.path.join(templates_dir, "db", "env"),
        db_conf_env,
        db_password=db_password)

render(os.path.join(templates_dir, "proxy", "nginx.http.conf"),
        proxy_conf)

render(os.path.join(templates_dir, "jenkins", "env"),
        jenkins_env,
        jenkins_host_ip=jenkins_host_ip,
        jenkins_host_port=jenkins_host_port,
        jenkins_node_ip=jenkins_node_ip,
        jenkins_node_ssh_port=jenkins_node_ssh_port,
        jenkins_node_username=jenkins_node_username,
        jenkins_node_password=jenkins_node_password,
        jenkins_node_volume=jenkins_node_volume)
    
render(os.path.join(templates_dir, "gogits", "app.ini"),
        gogits_conf,
        gogits_host_ip=gogits_host_ip,
        gogits_host_port=gogits_host_port,
        gogits_ssh_port=gogits_ssh_port)

render(os.path.join(templates_dir, "grafana", "kubernetes-datasource.json"),
        grafana_k8s_ds,
        kube_master_ip=kube_master_ip,
        kube_master_port=kube_master_port)

render(os.path.join(templates_dir, "grafana", "graphite-datasource.json"),
        grafana_graphite_ds)

shutil.copy(os.path.join(templates_dir, "grafana", "kubernetes-dashboard.json"), grafana_dashboard)

render(os.path.join(templates_dir, "grafana", "kubernetes.json"),
        grafana_k8s)

shutil.copy(os.path.join(templates_dir, "grafana", "notifications.json"), grafana_notifications)

render(os.path.join(templates_dir, "elasticsearch", "env"),
        elasticsearch_env,
        es_java_opts="-Xms%sm -Xmx%sm"%(elaseticsearch_memory_in_megabytes,elaseticsearch_memory_in_megabytes))

if os.path.exists(kibana_config_dir):
    shutil.rmtree(kibana_config_dir)
shutil.copytree(os.path.join(templates_dir, "kibana"), kibana_config_dir)

print("The configuration files are ready, please use docker-compose to start the service.")
