#!/usr/bin/python

# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# TO RUN
# source scripts/setup_venv.sh
# xos-migrate [-s <service-name>] [-r ~/cord]
# eg: xos-migrate -r ~/Sites/cord -s core -s fabric

# TODO
# - add support to specify a name to be given to the generated migration (--name parameter in django makemigrations)
# - add support to generate empty migrations (needed for data-only migrations)

import os
import sys
import argparse
import yaml
import shutil
from xosgenx.generator import XOSProcessor, XOSProcessorArgs
from xosconfig import Config
from multistructlog import create_logger


def get_abs_path(dir_):
    """ Convert a path specified by the user, which might be relative or based on
        home directory location, into an absolute path.
    """
    if os.path.isabs(dir_):
        return os.path.realpath(dir_)
    if dir_[0] == "~" and not os.path.exists(dir_):
        dir_ = os.path.expanduser(dir_)
        return os.path.abspath(dir_)
    return os.path.abspath(os.path.join(os.getcwd(), dir_))


def get_migration_library_path(dir_):
    """ Return a directory relative to the location of the migration library """
    return os.path.dirname(os.path.realpath(__file__)) + "/" + dir_


def print_banner(root):
    log.info(r"---------------------------------------------------------------")
    log.info(r"                                    _                  __      ")
    log.info(r"   _  ______  _____      ____ ___  (_)___ __________ _/ /____  ")
    log.info(r"  | |/_/ __ \/ ___/_____/ __ `__ \/ / __ `/ ___/ __ `/ __/ _ \ ")
    log.info(r" _>  </ /_/ (__  )_____/ / / / / / / /_/ / /  / /_/ / /_/  __/ ")
    log.info(r"/_/|_|\____/____/     /_/ /_/ /_/_/\__, /_/   \__,_/\__/\___/  ")
    log.info(r"                                  /____/                       ")
    log.info(r"---------------------------------------------------------------")
    log.debug("CORD repo root", root=root)
    log.debug("Storing logs in: %s" % os.environ["LOG_FILE"])
    log.debug(r"---------------------------------------------------------------")


def generate_core_models(core_dir):
    core_xproto = os.path.join(core_dir, "core.xproto")

    args = XOSProcessorArgs(
        output=core_dir,
        target="django.xtarget",
        dest_extension="py",
        write_to_file="model",
        files=[core_xproto],
    )
    XOSProcessor.process(args)

    security_args = XOSProcessorArgs(
        output=core_dir,
        target="django-security.xtarget",
        dest_file="security.py",
        write_to_file="single",
        files=[core_xproto],
    )

    XOSProcessor.process(security_args)

    init_args = XOSProcessorArgs(
        output=core_dir,
        target="init.xtarget",
        dest_file="__init__.py",
        write_to_file="single",
        files=[core_xproto],
    )
    XOSProcessor.process(init_args)


def find_xproto_in_folder(path):
    """
    Recursively iterate a folder tree to look for any xProto file.
    We use this function in case that the name of the xProto is different from the name of the folder (eg: olt-service)
    :param path: the root folder to start the search
    :return: [string]
    """
    xprotos = []
    for fn in os.listdir(path):
        # skip hidden files and folders. plus other useless things
        if fn.startswith(".") or fn == "venv-xos" or fn == "htmlcov":
            continue
        full_path = os.path.join(path, fn)
        if fn.endswith(".xproto"):
            xprotos.append(full_path)
        elif os.path.isdir(full_path):
            xprotos = xprotos + find_xproto_in_folder(full_path)
    return xprotos


def find_decls_models(path):
    """
    Recursively iterate a folder tree to look for any models.py file.
    This files contain the base model for _decl generated models.
    :param path: the root folder to start the search
    :return: [string]
    """
    decls = []
    for fn in os.listdir(path):
        # skip hidden files and folders. plus other useless things
        if fn.startswith(".") or fn == "venv-xos" or fn == "htmlcov":
            continue
        full_path = os.path.join(path, fn)
        if fn == "models.py":
            decls.append(full_path)
        elif os.path.isdir(full_path):
            decls = decls + find_decls_models(full_path)
    return decls


def get_service_name_from_config(path):
    """
    Given a service folder look for the config.yaml file and find the name
    :param path: the root folder to start the search
    :return: string
    """
    config = os.path.join(path, "xos/synchronizer/config.yaml")
    if not os.path.isfile(config):
        raise Exception("Config file not found at: %s" % config)

    cfg_file = open(config)
    cfg = yaml.safe_load(cfg_file)
    return cfg["name"]


def generate_service_models(service_dir, service_dest_dir, service_name):
    """
    Generate the django code starting from xProto for a given service.
    :param service_dir: string (path to the folder)
    :param service_name: string (name of the service)
    :return: void
    """
    xprotos = find_xproto_in_folder(service_dir)
    decls = find_decls_models(service_dir)
    log.debug("Generating models for %s from files %s" % (service_name, ", ".join(xprotos)))
    out_dir = os.path.join(service_dest_dir, service_name)
    if not os.path.isdir(out_dir):
        os.mkdir(out_dir)

    args = XOSProcessorArgs(
        output=out_dir,
        files=xprotos,
        target="service.xtarget",
        write_to_file="target",
    )
    XOSProcessor.process(args)

    security_args = XOSProcessorArgs(
        output=out_dir,
        target="django-security.xtarget",
        dest_file="security.py",
        write_to_file="single",
        files=xprotos,
    )

    XOSProcessor.process(security_args)

    init_py_filename = os.path.join(out_dir, "__init__.py")
    if not os.path.exists(init_py_filename):
        open(init_py_filename, "w").write("# created by dynamicbuild")

    # copy over models.py files from the service
    if len(decls) > 0:
        for file in decls:
            fn = os.path.basename(file)
            src_fn = file
            dest_fn = os.path.join(out_dir, fn)
            log.debug("Copying models.py from %s to %s" % (src_fn, dest_fn))
            shutil.copyfile(src_fn, dest_fn)

    # copy existing migrations from the service, otherwise they won't be incremental
    src_dir = os.path.join(service_dir, "xos", "synchronizer", "migrations")
    if os.path.isdir(src_dir):
        dest_dir = os.path.join(out_dir, "migrations")
        if os.path.isdir(dest_dir):
            shutil.rmtree(dest_dir)  # empty the folder, we'll copy everything again
        shutil.copytree(src_dir, dest_dir)


def copy_service_migrations(service_dir, service_dest_dir, service_name):
    """
    Once the migrations are generated, copy them in the correct location
    :param service_dir: string (path to the folder)
    :param service_name: string (name of the service)
    :return: void
    """
    log.debug("Copying %s migrations to %s" % (service_name, service_dir))
    migration_dir = os.path.join(service_dest_dir, service_name, "migrations")
    dest_dir = os.path.join(service_dir, "xos", "synchronizer", "migrations")
    if os.path.isdir(dest_dir):
        shutil.rmtree(dest_dir)  # empty the folder, we'll copy everything again
    shutil.copytree(migration_dir, dest_dir)
    # clean after the tool, generated migrations has been moved in the service repo
    shutil.rmtree(get_abs_path(os.path.join(migration_dir, "../")))


def monkey_patch_migration_template():
    import django
    django.setup()

    import django.db.migrations.writer as dj
    dj.MIGRATION_TEMPLATE = """\
# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# -*- coding: utf-8 -*-
# Generated by Django %(version)s on %(timestamp)s
from __future__ import unicode_literals

%(imports)s

class Migration(migrations.Migration):
%(replaces_str)s%(initial_str)s
    dependencies = [
%(dependencies)s\
    ]

    operations = [
%(operations)s\
    ]
"""


def configure_logging(verbose):
    global log
    # INITIALIZING LOGGER
    Config.init()

    cfg = Config().get("logging")
    if verbose:
        cfg["handlers"]["console"]["level"] = "DEBUG"

    log = create_logger(cfg)


# SETTING ENV
os.environ["LOG_FILE"] = get_migration_library_path("django.log")
os.environ["XOS_CONFIG_SCHEMA"] = get_migration_library_path("migration_cfg_schema.yaml")
os.environ["XOS_CONFIG_FILE"] = get_migration_library_path("migration_cfg.yaml")
os.environ["MIGRATIONS"] = "true"
# this is populated in case we generate migrations for services and it's used in settings.py
os.environ["INSTALLED_APPS"] = ""

# PARAMS
parser = argparse.ArgumentParser(description="XOS Migrations")
required = parser.add_argument_group("required arguments")

required.add_argument(
    "-s",
    "--service",
    action="append",
    required=True,
    dest="service_names",
    help="The name of the folder containing the service in cord/orchestration/xos_services"
)

parser.add_argument(
    "-r",
    "--repo",
    default=get_abs_path("~/cord"),
    dest="repo_root",
    help="The location of the folder containing the CORD repo root (default to ~/cord)"
)

parser.add_argument(
    "--check",
    default=False,
    action="store_true",
    dest="check",
    help="Check if the migrations are generated for a given service. Does not apply any change."
)

parser.add_argument(
    "-v",
    "--verbose",
    help="increase log verbosity",
    dest="verbose",
    action="store_true"
)


def run():
    # cleaning up from possible incorrect states
    if "INSTALLED_APPS" in os.environ:
        del os.environ["INSTALLED_APPS"]

    args = parser.parse_args()

    configure_logging(args.verbose)

    print_banner(args.repo_root)

    # find absolute path to the code
    xos_path = get_abs_path(os.path.join(args.repo_root, "orchestration/xos/xos/"))
    core_dir = get_abs_path(os.path.join(xos_path, "core/models/"))
    service_base_dir = get_abs_path(os.path.join(xos_path, "../../xos_services/"))
    service_dest_dir = get_abs_path(os.path.join(xos_path, "services/"))

    # we need to append the xos folder to sys.path
    original_sys_path = sys.path
    sys.path.append(xos_path)

    log.info("Services: %s" % ", ".join(args.service_names))

    django_cli_args = ['xos-migrate.py', "makemigrations"]

    # generate the code for each service and create a list of parameters to pass to django
    app_list = []
    for service in args.service_names:
        # NOTE we need core models to be there as all the services depend on them
        generate_core_models(core_dir)
        if service == "core":
            django_cli_args.append("core")
        else:
            service_dir = os.path.join(service_base_dir, service)
            service_name = get_service_name_from_config(service_dir)
            generate_service_models(service_dir, service_dest_dir, service_name)
            app_list.append("services.%s" % service_name)

            django_cli_args.append(service_name)

    if len(app_list) > 0:
        os.environ["INSTALLED_APPS"] = ",".join(app_list)

    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xos.settings")

    monkey_patch_migration_template()

    if args.check:
        django_cli_args.append("--check")
        django_cli_args.append("--dry-run")

    from django.core.management import execute_from_command_line

    try:
        log.debug("Django CLI Args", args=django_cli_args)
        execute_from_command_line(django_cli_args)
        returncode = 0
    except SystemExit as e:
        returncode = e.message

    if returncode != 0:
        if args.check:
            log.error("Migrations are not up to date with the service changes!")
        else:
            log.error("An error occurred")
        sys.exit(returncode)

    # copying migrations back to the service
    for service in args.service_names:
        if service == "core":
            # we don't need to copy migrations for the core
            continue
        else:
            service_dir = os.path.join(service_base_dir, service)
            service_name = get_service_name_from_config(service_dir)
            copy_service_migrations(service_dir, service_dest_dir, service_name)

    # restore orginal sys.path
    sys.path = original_sys_path
