#!/usr/bin/env python3

import sys
import traceback
import os
import logging
import json
from utils import utils

dir_path = os.path.dirname(os.path.realpath(__file__))
conf_dir_path=dir_path + "/conf"
output_dir_path=dir_path + "/output"
tmp_conf_dir_path=dir_path + "/tmp_conf"
SBX_CONF_FILE_ORIG=dir_path + "/input/sbx_conf_template"
SBX_CONF_FILE=tmp_conf_dir_path + "/sbx.conf"
USER_DATA_FILE=tmp_conf_dir_path + "/user-data"
META_DATA_FILE=tmp_conf_dir_path + "/meta-data"
EMS_CONFIG_JSON_FILE=conf_dir_path + "/emsConfig.json"
OAM_CONFIG_JSON_FILE=conf_dir_path + "/oamConfig.json"
TSBC_CONFIG_JSON_FILE=conf_dir_path + "/tsbcConfig.json"
EXTRA_CONFIG_JSON_FILE=conf_dir_path + "/extraConfig.json"

'''
Fname: getJsonConfig
Desc : Creates json config files from given data
Params:
  1. indata: Data dictionary that contains the config params
  2. ctype:  Config type that is passed. Allowed values ['CLEAR', 'EMS', 'OAM', 'TSBC', 'EXTRA_CONFIG']
             CLEAR:        Clears all old config files
             EMS:          Creates ems config
             OAM:          Creates oam config
             TSBC:         Creates tsbc config
             EXTRA_CONFIG: Creates extra config that is not part of sbx.conf
Returns: Returns the name of file created based on ctype passed
'''
def genJsonConfig(indata, ctype):
    if ctype == "CLEAR":
        os.system("rm -f " + EMS_CONFIG_JSON_FILE + " " + OAM_CONFIG_JSON_FILE)
        return "Done"
    if ctype == "EMS":
        data = {
                "EmsUsername"       :indata["emsName"],
                "EmsPassword"       :indata["emsPass"],
                "EmsIP"             :[indata["emsIp1"],indata["emsIp2"]],
                "EmsPrivateNodeParameters": {
                        "cluster_id"        :indata["clusterId"],
                        "vnfc_id"           :indata["vnfcId"]
                },
                "EmsDownloadConfig" :indata["downloadEmsConfig"]
                }
        file_name=EMS_CONFIG_JSON_FILE
    if ctype == "OAM":
        data = {
                "OamIP"             : [indata["oamIp1"],indata["oamIp2"]],
                "Oam1Ip"            : indata["oamIp1"],
                "Oam2Ip"            : indata["oamIp2"]
                }
        file_name=OAM_CONFIG_JSON_FILE

    if ctype == "TSBC":
        data = indata
        file_name=TSBC_CONFIG_JSON_FILE

    # All the additional parameters that are not supposed to be in sbx.conf but need to be present in userData.json
    # should be parsed in 'EXTRA_CONFIG'. Through this all these new parameters will go into extraConfig.json and
    # these parameters will eventually be merged into final userData.json
    if ctype == "EXTRA_CONFIG":
        data = {
                "HAFaultDetectionMode": indata["haFaultDetectionMode"]
               }
        file_name=EXTRA_CONFIG_JSON_FILE

    with open(file_name, 'w') as outfile:  
        json.dump(data, outfile, ensure_ascii=False, indent=4)

    return file_name

def genConfig(data, role):
    """
     Desc: Generate the config drive for the instance
    :param data:
    :param role: Installed Role of the Instance
    :return:
    """
    name = ""
    conf = []
    sbxConfOrig = open(SBX_CONF_FILE_ORIG, "r")
    for line in sbxConfOrig:
        line = line.strip('\n')
        if not line.rstrip():
            continue
        if int(data["mgtIpType"]) == 2:
            if (-1 != line.find("nif1Ipaddr=")):
                line = "nif1Ipaddr=0.0.0.0"
            if (-1 != line.find("nif1Netmask=")):
                line = "nif1Netmask=0.0.0.0"
            if (-1 != line.find("nif1GatewayIpaddr=")):
                line = "nif1GatewayIpaddr=0.0.0.0"
        if role.upper() == "ACTIVE":
            if (-1 != line.find("role=")):
                line = "role=" + str(1)
            if (-1 != line.find("systemName=")):
                line = "systemName=" + data["systemName"]
            if (-1 != line.find("ceName=")):
                line = "ceName=" + data["ceName"]
            if (-1 != line.find("peerCeName=")):
                line = "peerCeName=" + data["peerCeName"]
            if int(data["mgtIpType"]) == 1 or int(data["mgtIpType"]) == 3:
                if (-1 != line.find("nif1Ipaddr=")):
                    line = "nif1Ipaddr=" + data["mgtIp"]
                if (-1 != line.find("nif1Netmask=")):
                    line = "nif1Netmask=" + utils.cidr(int(data["mgtPrefix"]))
                if (-1 != line.find("nif1GatewayIpaddr=")):
                    line = "nif1GatewayIpaddr=" + data["mgtGw"]
            if int(data["mgtIpType"]) == 2 or int(data["mgtIpType"]) == 3:
                if (-1 != line.find("nif1IpaddrV6=")):
                    line = "nif1IpaddrV6=" + data["mgtIpV6"]
                if (-1 != line.find("nif1NetprefixV6=")):
                    line = "nif1NetprefixV6=" + data["mgtPrefixV6"]
                if (-1 != line.find("nif1GatewayIpaddrV6=")):
                    line = "nif1GatewayIpaddrV6=" + data["mgtGwV6"]
            #Seting default values to nif5
            if int(data["isMgt1Conf"]) == 2 or int(data["mgt1IpType"]) == 2:
                if (-1 != line.find("nif5Ipaddr=")):
                    line = "nif5Ipaddr=0.0.0.0"
                if (-1 != line.find("nif5Netmask=")):
                    line = "nif5Netmask=0.0.0.0"
                if (-1 != line.find("nif5GatewayIpaddr=")):
                    line = "nif5GatewayIpaddr=0.0.0.0"
            if int(data["isMgt1Conf"]) == 2 or int(data["mgt1IpType"]) == 1:
                if (-1 != line.find("nif5IpaddrV6=")):
                    line = "nif5IpaddrV6=::"
                if (-1 != line.find("nif5NetprefixV6=")):
                    line = "nif5NetprefixV6=0"
                if (-1 != line.find("nif5GatewayIpaddrV6=")):
                    line = "nif5GatewayIpaddrV6=::"
            if int(data["isMgt1Conf"]) == 1:
                if int(data["mgt1IpType"]) == 1 or int(data["mgt1IpType"]) == 3:
                    if (-1 != line.find("nif5Ipaddr=")):
                        line = "nif5Ipaddr=" + data["mgt1Ip"]
                    if (-1 != line.find("nif5Netmask=")):
                        line = "nif5Netmask=" + utils.cidr(int(data["mgt1Prefix"]))
                    if (-1 != line.find("nif5GatewayIpaddr=")):
                        line = "nif5GatewayIpaddr=" + data["mgt1Gw"]
                if int(data["mgt1IpType"]) == 2 or int(data["mgt1IpType"]) == 3:
                    if (-1 != line.find("nif5IpaddrV6=")):
                        line = "nif5IpaddrV6=" + data["mgt1IpV6"]
                    if (-1 != line.find("nif5NetprefixV6=")):
                        line = "nif5NetprefixV6=" + data["mgt1PrefixV6"]
                    if (-1 != line.find("nif5GatewayIpaddrV6=")):
                        line = "nif5GatewayIpaddrV6=" + data["mgt1GwV6"]
            if (-1 != line.find("ntpServerIpaddr=")):
                line = "ntpServerIpaddr=" + data["ntpIp"]
            if (-1 != line.find("activePrimaryInterCeIpaddr=")):
                line = "activePrimaryInterCeIpaddr=" + data["haIp"]
            if data["installType"] == 2:
                if (-1 != line.find("standbyPrimaryInterCeIpaddr=")):
                    line = "standbyPrimaryInterCeIpaddr=" + data["peerHaIp"]
            if data["installType"] == 2 or data["haMode"] == "Nto1":
                if (-1 != line.find("defaultNetmask=")):
                    line = "defaultNetmask=" + utils.cidr(int(data["haPrefix"]))
                if (-1 != line.find("defaultInterCeNetmask=")):
                    line = "defaultInterCeNetmask=" + utils.cidr(int(data["haPrefix"]))
            if (-1 != line.find("timeZoneIndex=")):
                line = "timeZoneIndex=" + str(data["timezone"])
            if data["haMode"] == "1to1" and (-1 != line.find("tipcID=")):
                line = "tipcID=" + str(data["tipc"])
            if (-1 != line.find("sbctype=")):
                line = "sbctype=" + data["sbctype"].lower()
            if (-1 != line.find("personality=")):
                line = "personality=" + str(data["personality"])
            if data["installType"] == 2 and role.upper() == "ACTIVE":
                if (-1 != line.find("rgIp=")):
                    line = "rgIp=" + data["peerHaIp"]
            if data["haMode"] == "Nto1":
                if (-1 != line.find("rgIp=")):
                    line = "rgIp=" + data["rgIp"]
            if (-1 != line.find("haMode=")):
                line = "haMode=" + data["haMode"]
            conf.append(line)
            name = "config_drive_" + data["ceName"].lower() + ".iso"
        elif role.upper() == "STANDBY":
            if (-1 != line.find("role=")):
                line = "role=" + str(2)
            if (-1 != line.find("systemName=")):
                line = "systemName=" + data["systemName"]
            if data["haMode"] == "1to1":
                if (-1 != line.find("ceName=")):
                    line = "ceName=" + data["peerCeName"]
                if (-1 != line.find("peerCeName=")):
                    line = "peerCeName=" + data["ceName"]
                if int(data["peerMgtIpType"]) == 1 or int(data["peerMgtIpType"]) == 3:
                    if (-1 != line.find("nif1Ipaddr=")):
                        line = "nif1Ipaddr=" + data["peerMgtIp"]
                    if (-1 != line.find("nif1Netmask=")):
                        line = "nif1Netmask=" + utils.cidr(int(data["peerMgtPrefix"]))
                    if (-1 != line.find("nif1GatewayIpaddr=")):
                        line = "nif1GatewayIpaddr=" + data["peerMgtGw"]
                if int(data["peerMgtIpType"]) == 2 or int(data["peerMgtIpType"]) == 3:
                    if (-1 != line.find("nif1IpaddrV6=")):
                        line = "nif1IpaddrV6=" + data["peerMgtIpV6"]
                    if (-1 != line.find("nif1NetprefixV6=")):
                        line = "nif1NetprefixV6=" + data["peerMgtPrefixV6"]
                    if (-1 != line.find("nif1GatewayIpaddrV6=")):
                        line = "nif1GatewayIpaddrV6=" + data["peerMgtGwV6"]
                if int(data["isMgt1Conf"]) == 2 or int(data["peerMgt1IpType"]) == 2:
                    if (-1 != line.find("nif5Ipaddr=")):
                        line = "nif5Ipaddr=0.0.0.0"
                    if (-1 != line.find("nif5Netmask=")):
                        line = "nif5Netmask=0.0.0.0"
                    if (-1 != line.find("nif5GatewayIpaddr=")):
                        line = "nif5GatewayIpaddr=0.0.0.0"
                if int(data["isMgt1Conf"]) == 2 or int(data["peerMgt1IpType"]) == 1:
                    if (-1 != line.find("nif5IpaddrV6=")):
                        line = "nif5IpaddrV6=::"
                    if (-1 != line.find("nif5NetprefixV6=")):
                        line = "nif5NetprefixV6=0"
                    if (-1 != line.find("nif5GatewayIpaddrV6=")):
                        line = "nif5GatewayIpaddrV6=::"
                if int(data["isMgt1Conf"]) == 1:
                    if int(data["peerMgt1IpType"]) == 1 or int(data["peerMgt1IpType"]) == 3:
                        if (-1 != line.find("nif5Ipaddr=")):
                            line = "nif5Ipaddr=" + data["peerMgt1Ip"]
                        if (-1 != line.find("nif5Netmask=")):
                            line = "nif5Netmask=" + utils.cidr(int(data["peerMgt1Prefix"]))
                        if (-1 != line.find("nif5GatewayIpaddr=")):
                            line = "nif5GatewayIpaddr=" + data["peerMgt1Gw"]
                    if int(data["peerMgt1IpType"]) == 2 or int(data["peerMgt1IpType"]) == 3:
                        if (-1 != line.find("nif5IpaddrV6=")):
                            line = "nif5IpaddrV6=" + data["peerMgt1IpV6"]
                        if (-1 != line.find("nif5NetprefixV6=")):
                            line = "nif5NetprefixV6=" + data["peerMgt1PrefixV6"]
                        if (-1 != line.find("nif5GatewayIpaddrV6=")):
                            line = "nif5GatewayIpaddrV6=" + data["peerMgt1GwV6"]
                if (-1 != line.find("activePrimaryInterCeIpaddr=")):   
                        line = "activePrimaryInterCeIpaddr=" + data["haIp"]
                if (-1 != line.find("standbyPrimaryInterCeIpaddr=")):
                    line = "standbyPrimaryInterCeIpaddr=" + data["peerHaIp"]
                if (-1 != line.find("defaultNetmask=")):
                    line = "defaultNetmask=" + utils.cidr(int(data["haPrefix"]))
                if (-1 != line.find("defaultInterCeNetmask=")):
                    line = "defaultInterCeNetmask=" + utils.cidr(int(data["haPrefix"]))
            else:
                if (-1 != line.find("ceName=")):
                    line = "ceName=" + data["ceName"]
                if (-1 != line.find("peerCeName=")):
                    line = "peerCeName=" + data["peerCeName"]
                if int(data["mgtIpType"]) == 1 or int(data["mgtIpType"]) == 3:
                    if (-1 != line.find("nif1Ipaddr=")):
                        line = "nif1Ipaddr=" + data["mgtIp"]
                    if (-1 != line.find("nif1Netmask=")):
                        line = "nif1Netmask=" + utils.cidr(int(data["mgtPrefix"]))
                    if (-1 != line.find("nif1GatewayIpaddr=")):
                        line = "nif1GatewayIpaddr=" + data["mgtGw"]
                if int(data["mgtIpType"]) == 2 or int(data["mgtIpType"]) == 3:
                    if (-1 != line.find("nif1IpaddrV6=")):
                        line = "nif1IpaddrV6=" + data["mgtIpV6"]
                    if (-1 != line.find("nif1NetprefixV6=")):
                        line = "nif1NetprefixV6=" + data["mgtPrefixV6"]
                    if (-1 != line.find("nif1GatewayIpaddrV6=")):
                        line = "nif1GatewayIpaddrV6=" + data["mgtGwV6"]
                if (-1 != line.find("standbyPrimaryInterCeIpaddr=")):
                    line = "standbyPrimaryInterCeIpaddr=" + data["haIp"]
                if (-1 != line.find("defaultNetmask=")):
                    line = "defaultNetmask=" + utils.cidr(int(data["haPrefix"]))
                if (-1 != line.find("defaultInterCeNetmask=")):
                    line = "defaultInterCeNetmask=" + utils.cidr(int(data["haPrefix"]))
            if (-1 != line.find("ntpServerIpaddr=")):
                line = "ntpServerIpaddr=" + data["ntpIp"]
            if (-1 != line.find("timeZoneIndex=")):
                line = "timeZoneIndex=" + str(data["timezone"])
            if data["haMode"] == "1to1" and (-1 != line.find("tipcID=")):
                line = "tipcID=" + str(data["tipc"])
            if (-1 != line.find("sbctype=")):
                line = "sbctype=" + data["sbctype"].lower()
            if (-1 != line.find("personality=")):               
                line = "personality=" + str(data["personality"])
            if data["installType"] == 2 and role.upper() == "STANDBY":
                if (-1 != line.find("rgIp=")):
                    line = "rgIp=" + data["haIp"]
            if data["haMode"] == "Nto1":
                if (-1 != line.find("rgIp=")):
                    line = "rgIp=" + data["rgIp"]
            if (-1 != line.find("haMode=")):
                line = "haMode=" + data["haMode"]
            conf.append(line)
            if data["haMode"] == "Nto1":
                name = "config_drive_" + data["ceName"].lower() + ".iso"
            else:
                name = "config_drive_" + data["peerCeName"].lower() + ".iso"

        if (-1 != line.find("enableREST=")):
            line = "enableREST=" + str(data["enableREST"])
        if (-1 != line.find("enableCoreEMA=")):
            line = "enableCoreEma=" + str(data["enableCoreEMA"])
        if (-1 != line.find("enableTS=")):
            line = "enableTS=" + str(data["enableTS"])

    sbxConfOrig.close()
    if os.path.isdir(tmp_conf_dir_path):
        os.system("rm -rf " + tmp_conf_dir_path)
    if not os.path.isdir(output_dir_path):
        os.system("mkdir -p " + output_dir_path)
    os.system("mkdir -p " + tmp_conf_dir_path)
    sbxConf = open(SBX_CONF_FILE, "w")
    sbxConf.write("\n".join(conf))
    os.fsync(sbxConf)
    sbxConf.close()
    os.system("cp -f " + conf_dir_path + "/* " + tmp_conf_dir_path + "/")
    if data["sshKeyReq"] == 1:
        os.system("sed -i \"s|_ADMIN_SSH_KEY_|" + data["adminSshKey"] + "|\" " + USER_DATA_FILE)
        os.system("sed -i \"s|_LINUXADMIN_SSH_KEY_|" + data["linuxadminSshKey"] + "|\" " + USER_DATA_FILE)
    elif data["sshKeyReq"] == 2:
        os.system("rm -f " + USER_DATA_FILE + "; touch " + USER_DATA_FILE)
    if not os.path.isfile(META_DATA_FILE):
        os.system("touch " + META_DATA_FILE)
    os.system("genisoimage -o " + output_dir_path + "/" + name + " -V cidata -r " + tmp_conf_dir_path)
    return name
