#!/usr/bin/env python

import getopt
import json
import sys

import gc

from cisco_sdwan_policy.Helper.PolicyLoader import PolicyLoader

# def update_template(data):
#     data["templateId"] = uuid_pairs[data["templateId"]]
#     if data.get("subTemplates"):
#         for sub_tmp in data["subTemplates"]:
#             sub_tmp["templateId"] = uuid_pairs[sub_tmp["templateId"]]
#     return data
#
#
# def load_template(rest, data):
#     result = rest.get_request("template/feature/object/{}".format(data["templateId"]))
#     info = result.json()
#     if data.get("subTemplates"):
#         for sub_tmp in data["subTemplates"]:
#             load_template(rest,sub_tmp)
#     if not loaded_templates.get(data["templateId"]):
#         loaded_templates[data['templateId']] = info
#     # print(result.json())


def backup_policy(server_info,policy_name=None):

    # Load all policy in vManage
    pl = PolicyLoader.init(server_info)
    pl.load()
    if policy_name:
        # Backup only selected policy
        # Will be kinda complicated since needs to remove unused policies.
        # old_main = pl.main_policies
        # old_topo = pl.topo_policies
        # old_traffic = pl.traffic_policies
        # old_list = pl.list_policies

        # Find the policy to move
        policy_to_move = None
        for i in pl.main_policies:
            if i.name == policy_name:
                policy_to_move = i
        if not policy_to_move:
            raise Exception("Policy name not found {}".format(policy_name))
        output ={
            "list_policies":[i.export() for i in pl.list_policies],
            "topo_policies":[i.export() for i in pl.topo_policies],
            "traffic_policies":[i.export() for i in pl.traffic_policies],
            "main_policies":[policy_to_move.export()],
            "only_ref":True
        }
        return json.dumps(output)
    else:
        return pl.save_to_json()
    # Backup fininshed

def restore_policy(server_info,json_data):

    # Start recovery process
    pl = PolicyLoader.init(server_info)
    pl.load()
    if json.loads(json_data).get("only_ref"):
        pl.load_from_json(json_data, only_ref=True)
    else:
        pl.load_from_json(json_data)

def transfer_policy(server1,server2,policy_name=None):
    resp = backup_policy(server1,policy_name)
    restore_policy(server2,resp)



def print_help():
    print("[*] A tool for backup policies / transfer policies between vManage controllers.")
    print("[*] Usage:")
    print("[*] --mode : transfer/backup/restore")
    print(
        "[*]         If choosing transfer, server1 & server2's info need to be given in prompt. Otherwise just input server1's info.")
    print("[*] --all-policy")
    print("[*]          If given, backup all templates in controller, can't be used with --policy.")
    print("[*] --policy : policy name")
    print("[*]         Input policy name for backup.")
    print("[*] --file : file path")
    print(
        "[*]         Input a file path to save/read file in backup & restore modes, in transfer mode this parameter is not needed.")
    print("[*] --server1-ip : Server 1's hostname")
    print("[*]         Input vManage Server1's hostname.")
    print("[*] --server1-port : Server 1's port")
    print("[*]         Input vManage Server1's port.")
    print("[*] --server1-user : Server 1's username")
    print("[*]         Input vManage Server1's username.")
    print("[*] --server1-pw : Server 1's password")
    print("[*]         Input vManage Server1's password.")
    print("[*] --server1-tenant : Server 1's tenant name")
    print("[*]         Input vManage Server1's tenant name, if not in multi tenant mode, skip this.")

    print("[*] --server2-ip : Server 2's hostname")
    print("[*]         Input vManage Server2's hostname.")
    print("[*] --server2-port : Server 2's port")
    print("[*]         Input vManage Server2's port.")
    print("[*] --server2-user : Server 2's username")
    print("[*]         Input vManage Server2's username.")
    print("[*] --server2-pw : Server 2's password")
    print("[*]         Input vManage Server2's password.")
    print("[*] --server2-tenant : Server 2's tenant name")
    print("[*]         Input vManage Server2's tenant name, if not in multi tenant mode, skip this.")
    print("[*]\n[*] Example:")
    print("[*] Transfer policy 'Policy1':")
    print(
        "[*] sdwan-policy-tool --mode=transfer --policy=Policy1 --server1-ip=10.0.0.1 --server1-port=443 --server1-user=admin --server1-pw=admin --server2-ip=10.0.0.2 --server2-port=443 --server2-user=admin --server2-pw=admin")
    print("[*] Backup all policy:")
    print(
        "[*] sdwan-policy-tool --mode=backup --all-policy --file=backup.json --server1-ip=10.0.0.1 --server1-port=443 --server1-user=admin --server1-pw=admin")
    print("[*] Restore policy from a file:")
    print(
        "[*] sdwan-policy-tool --mode=restore --file=backup.json --server1-ip=10.0.0.1 --server1-port=443 --server1-user=admin --server1-pw=admin")


if __name__ == '__main__':


    opts, args = getopt.getopt(sys.argv[1:], '-h-s1:-u1:-pw1:-p1:-t1:-s2:-u2:-pw2:-p2:-t2:-a-p:-m:-f', ['help', 'server1-ip=', 'server1-user=', 'server1-pw=', 'server1-port=', 'server1-tenant=','server2-ip=', 'server2-user=', 'server2-pw=', 'server2-port=', 'server2-tenant=', 'all-policy', 'policy=','mode=','file='])

    server1_user = server2_user = server1_port = server2_port = server1_pw = server2_pw =server1_ip = server2_ip =server1_tenant =server2_tenant = all_policy =policy_name = mode =file = None
    for opt_name, opt_value in opts:
        if opt_name in ('-h', '--help'):
            print_help()
            exit()

        if opt_name in ('-s1', '--server1-ip'):
            server1_ip = opt_value
            print("[*] Server1 IP is {}".format(server1_ip))
        if opt_name in ('-u1', '--server1-user'):
            server1_user = opt_value
            print("[*] Server1 Username is {}".format(server1_user))
        if opt_name in ('-pw1', '--server1-pw'):
            server1_pw = opt_value
            print("[*] Server1 Password is {}".format(server1_pw))
        if opt_name in ('-p1', '--server1-port'):
            server1_port = opt_value
            print("[*] Server1 Port is {}".format(server1_port))
        if opt_name in ('-t1', '--server1-tenant'):
            server1_tenant = opt_value
            print("[*] Server1 Tenant is {}".format(server1_tenant))


        if opt_name in ('-s2', '--server2-ip'):
            server2_ip = opt_value
            print("[*] Server2 IP is {}".format(server2_ip))
        if opt_name in ('-u2', '--server2-user'):
            server2_user = opt_value
            print("[*] Server2 Username is {}".format(server2_user))
        if opt_name in ('-pw2', '--server2-pw'):
            server2_pw = opt_value
            print("[*] Server2 Password is {}".format(server2_pw))
        if opt_name in ('-p2', '--server2-port'):
            server2_port = opt_value
            print("[*] Server2 Port is {}".format(server2_port))
        if opt_name in ('-t2', '--server2-tenant'):
            server2_tenant = opt_value
            print("[*] Server2 Tenant is {}".format(server2_tenant))

        if opt_name in ('-a', '--all-policy'):
            all_policy=True
            print("[*] Transfering all policy")
        if opt_name in ('-p', '--policy'):
            all_policy = False
            policy_name = opt_value
            print("[*] Transfering policy {}".format(policy_name))

        if opt_name in ('-m', '--mode'):
            if opt_value not in ["transfer","backup","restore"]:
                print("Please enter valid modes")
                exit()
            mode = opt_value
            print("[*] Choosing mode {}".format(mode))

        if opt_name in ('-f', '--file'):
            file = opt_value
            print("[*] Choosing file {}".format(mode))
    if not (mode and (all_policy or policy_name or mode=="restore")):
        print("Help : Need to input mode and choose if transfering all policy or single policy.")
        print_help()
        exit()

    if mode =="transfer":

        if None in [server1_ip,server2_ip, server1_user,server2_user,server1_pw,server2_pw,server1_port,server2_port]:
            print(
                "[*] Help: Please enter the server 1 and server 2's info for transfer.")
            exit()
    elif mode =="backup":
        if None in [server1_ip, server1_user,server1_pw,server1_port,file]:
            print(
                "[*] Help: Please enter the server 1's info for backup.")
            exit()
    elif mode =="restore":
        if None in [server1_ip, server1_user,server1_pw,server1_port,file]:
            print(
                "[*] Help: Please enter the server 1's info for restore.")
            exit()

    if mode =="transfer":
        server1_info = {
        "hostname": server1_ip,
        "port": server1_port,
        "username": server1_user,
        "password": server1_pw,
        "tenant": server1_tenant
        }

        server2_info = {
        "hostname": server2_ip,
        "port": server2_port,
        "username": server2_user,
        "password": server2_pw,
        "tenant": server2_tenant
        }

        transfer_policy(server1_info,server2_info,policy_name)
        print("Transfer Complete.")

    elif mode =="backup":
        server1_info = {
        "hostname": server1_ip,
        "port": server1_port,
        "username": server1_user,
        "password": server1_pw,
        "tenant": server1_tenant
        }


        data = backup_policy(server1_info,policy_name)
        with open(file,"w") as handler:
            handler.write(data)

        print("Backup Complete, store at: {}".format(file))

    elif mode =="restore":

        server1_info = {
        "hostname": server1_ip,
        "port": server1_port,
        "username": server1_user,
        "password": server1_pw,
        "tenant": server1_tenant
        }

        with open(file,"r") as handler:
            json_data = handler.read()
        restore_policy(server1_info,json_data)
        print("Restore Complete")


















