#!/usr/bin/env python
from __future__ import print_function

import gevent.monkey

gevent.monkey.patch_all()

import argparse
import os

from sepelib.core import config
from sepelib.mongo.util import register_database

from walle import audit_log
from walle.constants import VLAN_SCHEME_MTN, VLAN_SCHEME_SEARCH
from walle.clients import racktables

from walle.main import load_config
from walle.projects import Project


def validated_hbf_project_id(hbf_project_id_string):
    try:
        hbf_project_id = int(hbf_project_id_string, 16)
    except ValueError:
        raise ValueError("Invalid HBF project id: {}".format(hbf_project_id_string))

    try:
        projects_map = racktables.get_hbf_projects()
    except racktables.RequestException as e:
        raise RuntimeError("Can not validate HBF project id: {}".format(e))

    if hbf_project_id in projects_map:
        return hbf_project_id
    else:
        raise ValueError("Unknown HBF project id: {}".format(hbf_project_id_string))


def set_mtn(project, mtn_project_id):
    project.owned_vlans = [333, 700, 688, 788]
    project.vlan_scheme = VLAN_SCHEME_MTN
    project.native_vlan = 333
    project.extra_vlans = [688, 788]

    project.hbf_project_id = validated_hbf_project_id(mtn_project_id)


def set_rtc_vlan_scheme(project):
    project.owned_vlans = [604, 761, 688, 788]
    project.vlan_scheme = VLAN_SCHEME_SEARCH
    project.native_vlan = 604
    project.extra_vlans = [688, 788]

    del project.hbf_project_id


def clone_project(source_id, target_id, target_name, mtn_project_id=None, rtc_vlan_scheme=False,
                  dns_domain=None, reason=None, **kwargs):
    project = Project.objects.get(id=source_id)
    project.id = target_id
    project.name = target_name

    if mtn_project_id:
        set_mtn(project, mtn_project_id)

    if rtc_vlan_scheme:
        set_rtc_vlan_scheme(project)

    if dns_domain is not None:
        project.dns_domain = dns_domain

    issuer = os.environ["USER"] + "@"
    audit = audit_log.on_add_project(
        issuer, project_id=target_id, user_project=project.to_api_obj(Project.api_fields), reason=reason
    )

    with audit:
        project.save(force_insert=True)


def main():
    args = _parse_args()
    load_config(args)

    register_database("mongodb")

    if not args.yes:
        ans = raw_input("Do you really want to copy project [{}] to project [{}]({})? [y/N]: ".format(
            args.source_id, args.target_id, args.target_name))
        if ans.lower() not in ("y", "yes"):
            print("Action not taken.")
            return

    clone_project(**vars(args))
    print("Done.")


def _parse_args():
    parser = argparse.ArgumentParser(description="Clone one wall-e project to a new one.")
    parser.add_argument("-c", "--config", help="configuration file path")
    parser.add_argument("-d", "--debug", action="store_true", help="Set logging level to 'debug'")
    parser.add_argument("-y", "--yes", action="store_true",  help="Assume 'yes' to confirmation questions")

    parser.add_argument("source_id", metavar="source-id", help="Source project id")
    parser.add_argument("target_id", metavar="target-id", help="Target project id")
    parser.add_argument("target_name", metavar="target-name", help="Target project name")

    vlan_scheme = parser.add_mutually_exclusive_group()
    vlan_scheme.add_argument("--mtn-vlan-scheme", metavar="mtn-project-id", help="MTN project id")
    vlan_scheme.add_argument("--rtc-vlan-scheme", action="store_true", help="Set search VLAN scheme with RTC VLANs")

    parser.add_argument("--dns-domain", action="store", help="Set domain for DNS (if not specified - copy from source)")
    parser.add_argument("-m", "--reason", help="Reason message")

    config.augment_args_parser(parser)
    return parser.parse_args()


if __name__ == "__main__":
    main()
