#!/usr/bin/env python3
'''
Copyright 2017, Fujitsu Network Communications, Inc.
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.
'''

import os
import site
import sys
import shutil


if sys.version_info < (3, 6):
    print("Warriormigrate doesn't support Python version lower than 3.6, now exiting")
    sys.exit(0)

PIP_MODE = False
GIT_MODE = False


cli_args = sys.argv
if len(cli_args) > 1:
    if "--help" in cli_args:
        print("You can use this to migrate/merge the default warrior sub modules into warrior."
            "\nUsage:"
            "\n1. To install specific packages: -pkgs_list pkg1,pkg2,pkgn"
            "\n2. To install all packages: -pkgs_list all"
            "\n3. To specify mode: -mode git (or) -mode pip"
        )
        exit(1)
    if "-mode" in cli_args:
        mode_idx = cli_args.index("-mode")
        if len(cli_args) > mode_idx+1:
            mode = sys.argv[mode_idx+1]
            if str(mode).lower() == 'git':
                GIT_MODE = True
            elif str(mode).lower() == 'pip':
                PIP_MODE = True
            else:
                print('\033[91m' +
                    f"Unrecognized mode; it should be either 'git' or 'pip'" + '\033[0m')
                exit(1)
        else:
            print('\033[91m' +
                f"Mode not specified; it should be either 'git' or 'pip'" + '\033[0m')
            exit(1)
    else:
        try:
            import warrior
            PIP_MODE = True
        except:
            GIT_MODE = True
else:
    print("You can use this to migrate/merge the default warrior sub modules into warrior."
            "\nUsage:"
            "\n1. To install specific packages: -pkgs_list pkg1,pkg2,pkgn"
            "\n2. To install all packages: -pkgs_list all"
            "\n3. To specify mode: -mode git (or) -mode pip"
    )

def parse_input_packages():
    if "-pkgs_list" in cli_args:
            pkgs_list_idx = cli_args.index("-pkgs_list")
            if len(cli_args) > pkgs_list_idx+1:
                pkgs_str = cli_args[pkgs_list_idx+1]
                if pkgs_str.strip().lower() != 'all' and pkgs_str.strip().lower() != "":
                    parsed_pkgs = pkgs_str.split(",")
                    print("Input packages are: ", parsed_pkgs)
                    return parsed_pkgs
                elif pkgs_str.strip().lower() == 'all':
                    return ["warriorciregression", "warriorcli", "warriorcloudshell", 
                    "warriordemo", "warriorfile", "warriorgnmi", "warriorkafka", 
                    "warriormicroapps", "warriormongo", "warriornetconf", 
                    "warriornetwork", "warriorrest", "warriorselenium", "warriorserver", "warriorsnmp", "warriorwapp"]
                else:
                    print('\033[91m' +
                        f"Invalid value for -pkgs_list: \nSupported values are:\
                        \n1. To install specific packages: -pkgs_list pkg1,pkg2,pkg3,pkgn \
                        \n2. To install all warrior default modules: -pkgs_list all" + '\033[0m')
                    exit(1)
            else:
                print('\033[91m' +
                    f"Packages info not provided." + '\033[0m')
                exit(1)
    else:
        print('\033[91m' +
            f"Missing -pkgs_list option." + '\033[0m')
        exit(1)

def recursive_copy_with_exist_ok(src, dest, ignore=None):
    if os.path.isdir(src):
        if not os.path.isdir(dest):
            os.makedirs(dest)
        files = os.listdir(src)
        if ignore is not None:
            ignored = ignore
        else:
            ignored = []
        for f in files:
            if f not in ignored:
                recursive_copy_with_exist_ok(os.path.join(src, f),
                                    os.path.join(dest, f),
                                    ignore)
    else:
        shutil.copyfile(src, dest)

def copy_warrior_module_files(pkg_dir, warrior_path):
    pkg_actions_dir = os.path.join(pkg_dir, "Actions") if os.path.exists(os.path.join(pkg_dir, "Actions")) else ""
    pkg_driver_dir = os.path.join(pkg_dir, "ProductDrivers") if os.path.exists(os.path.join(pkg_dir, "ProductDrivers")) else ""
    pkg_utils_dir = os.path.join(pkg_dir, "Utils") if os.path.exists(os.path.join(pkg_dir, "Utils")) else ""
    pkg_classutils_dir = os.path.join(pkg_dir, "ClassUtils") if os.path.exists(os.path.join(pkg_dir, "ClassUtils")) else ""

    warrior_actions_dir = os.path.join(warrior_path, "Actions")
    warrior_productdrivers_dir = os.path.join(warrior_path, "ProductDrivers")
    warrior_utils_dir = os.path.join(warrior_path, "Framework", "Utils")
    warrior_classutils_dir = os.path.join(warrior_path, "Framework", "ClassUtils")

    print(f"Source dirs:\npkgdir: {pkg_dir}\npkg_actions_dir: {pkg_actions_dir}\npkg_driver_dir: {pkg_driver_dir}"\
        f"\npkg_utils_dir: {pkg_utils_dir}\npkg_classutils_dir: {pkg_classutils_dir}"
        )
    print(f"\nDestination dirs:\nwarrior dir: {warrior_path}\nwarrior_actions_dir: {warrior_actions_dir} \nwarrior_productdrivers_dir: {warrior_productdrivers_dir}"\
        f"\nwarrior_utils_dir: {warrior_utils_dir}\nwarrior_classutils_dir: {warrior_classutils_dir}"
        )
    #copy Actions files
    if pkg_actions_dir != "":
        actions = os.listdir(pkg_actions_dir)
        actions = list(set(actions) - {"__init__.py"})
        if actions:
            recursive_copy_with_exist_ok(pkg_actions_dir, warrior_actions_dir)
        else:
            print('\033[91m' + f"Empty dir: {pkg_actions_dir}" + '\033[0m')
    #copy ProductDrivers files
    if pkg_driver_dir != "":
        drivers = os.listdir(pkg_driver_dir)
        drivers = list(set(drivers) - {"__init__.py"})
        if drivers:
            recursive_copy_with_exist_ok(pkg_driver_dir, warrior_productdrivers_dir, ignore=['__init__.py'])
        else:
            print('\033[91m' + f"Empty dir: {pkg_driver_dir}" + '\033[0m')
    #copy Utils
    if pkg_utils_dir != "":
        utils = os.listdir(pkg_utils_dir)
        utils = list(set(utils) - {"__init__.py"})
        if utils:
            recursive_copy_with_exist_ok(pkg_utils_dir, warrior_utils_dir, ignore=['__init__.py'])
        else:
            print('\033[91m' + f"Empty dir: {pkg_utils_dir}" + '\033[0m')
    #copy ClassUtils
    if pkg_classutils_dir != "":
        classutils = os.listdir(pkg_classutils_dir)
        classutils = list(set(classutils) - {"__init__.py"})
        if classutils:
            recursive_copy_with_exist_ok(pkg_classutils_dir, warrior_classutils_dir)
        else:
            print('\033[91m' + f"Empty dir: {pkg_classutils_dir}" + '\033[0m')
            

if PIP_MODE:
    print("Migrations started in PIP mode")
    try:
        import warrior
    except:
        print('\033[91m' +
            f"Couldn't complete migration, first you need to install warriorframework package" + '\033[0m')
        exit(1)

    else:
        # warrior_path = "/".join(os.path.abspath(warrior.__file__).split("/")[:-1])
        warrior_path = os.path.dirname(os.path.abspath(warrior.__file__))
        print(f"Found warriorframework package at: '{warrior_path}'")
        input_packages = parse_input_packages()
        for pkg in input_packages:
            if pkg.strip() != "":
                try:
                    pkg_obj = __import__(pkg)
                except Exception as error:
                    print('\033[93m' + f"WARNING: Skipping {pkg} as it is not installed."+ '\033[0m')
                    continue
                else:
                    print(f"\n=================================== Migrating {pkg} package===================================")
                    pkg_dir = os.path.dirname(os.path.abspath(pkg_obj.__file__))
                    copy_warrior_module_files(pkg_dir, warrior_path)
                    print(f"=================================== {pkg} package migration completed ===================================")
            else:
                print('\033[93m' + f"WARNING: Found empty string as a package name, skipping as it is not valid." + '\033[0m')
                continue
              

if GIT_MODE:
    print("Migrations started in git mode")
    warrior_path = os.path.dirname(os.path.abspath(__file__))
    warrior_modules_path = os.path.join((os.path.dirname(warrior_path)), "warrior_modules")
    print(f"Found warriorframework source code at: '{warrior_path}'")
    input_packages = parse_input_packages()
    for pkg in input_packages:
        if pkg.strip() != "":
            pkg_parent = "warrior_"+pkg.split("warrior")[1] if pkg.startswith("warrior") else "warrior_"+pkg
            pkg_dir = os.path.join(warrior_modules_path, pkg_parent, pkg)
            if os.path.exists(pkg_dir):
                print(f"\n=================================== Migrating {pkg} package===================================")
                copy_warrior_module_files(pkg_dir, warrior_path)                
                print(f"=================================== {pkg} package migration completed ===================================")
            else:
                print('\033[93m' + f"WARNING: Skipping {pkg} as it matches none of the warrior default packages."+ '\033[0m')
                continue
        else:
            print('\033[93m' + f"WARNING: Found empty string as a package name, skipping as it is not valid." + '\033[0m')
            continue