# cli.py - Command line interface for automation
#
# Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com>
# Copyright 2020 Matt Harbison <mharbison72@gmail.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.

# no-check-code because Python 3 native.

import argparse
import os
import pathlib
import shutil
import sys

from . import venv

HERE = pathlib.Path(os.path.abspath(os.path.dirname(__file__)))
SOURCE_DIR = HERE.parent.parent.parent


def build_venv(python='', hg='', qt=None, output='', force=False, clean=False):
    if not os.path.isabs(python):
        raise Exception("--python arg must be an absolute path")

    if not os.path.isabs(hg):
        raise Exception("--hg arg must be an absolute path")

    if not os.path.isabs(hg):
        raise Exception("--hg arg must be an absolute path")

    if output and not os.path.isabs(output):
        raise Exception("--output arg must be an absolute path")

    pkg_path = pathlib.Path(hg) / 'contrib' / 'packaging'
    sys.path.insert(0, str(pkg_path))

    if not pkg_path.exists():
        raise Exception(
            "--hg arg must point to a Mercurial repository with packaging "
            "scripts"
        )

    build_dir = SOURCE_DIR / "build"
    python_exe = pathlib.Path(python)

    import hgpackaging.util as hgutil

    py_info = hgutil.python_exe_info(python_exe)

    if not output:
        version = str(py_info['version']).strip()
        arch = 'x64' if py_info['arch'] == '64bit' else 'x86'
        output = build_dir / ('venv-thg-py%s-%s' % (version, arch))
    else:
        output = pathlib.Path(output)

    if output.exists():
        if force:
            shutil.rmtree(output)
        else:
            raise Exception(
                "the output path already exists. (Use --force to overwrite)"
            )

    if py_info.get('py3'):
        venv.build_py3(SOURCE_DIR, pathlib.Path(hg), python_exe, output)
    elif qt is None:
        raise Exception(
            "--python arg must be Python 3.7 or later; or use venv_py2 instead"
        )
    else:
        # Delayed import to pick up sys.path modification
        from . import venv_py2

        venv_py2.build_py2(
            SOURCE_DIR,
            pathlib.Path(hg),
            pathlib.Path(qt),
            build_dir,
            python_exe,
            output,
            clean,
        )


def get_parser():
    parser = argparse.ArgumentParser()

    subparsers = parser.add_subparsers()

    sp = subparsers.add_parser("venv", help="Build py3 virtualenv")
    sp.add_argument("--python", required=True, help="path to python.exe to use")
    sp.add_argument("--hg", required=True, help="path to hg repo to use")
    sp.add_argument("--output", help="path to the new virtualenv")
    sp.add_argument(
        "--force",
        help="remove the output path before creating",
        action="store_true",
    )
    sp.set_defaults(func=build_venv)

    sp = subparsers.add_parser("venv_py2", help="Build py2 virtualenv")
    sp.add_argument("--python", required=True, help="path to python.exe to use")
    sp.add_argument("--hg", required=True, help="path to hg repo to use")
    sp.add_argument("--qt", required=True, help="path to Qt bin path to use")
    sp.add_argument("--output", help="path to the new virtualenv")
    sp.add_argument(
        "--force",
        help="remove the virtualenv if it exists",
        action="store_true",
    )
    sp.add_argument(
        "--clean",
        help="remove previous build output and cached downloads",
        action="store_true",
    )
    sp.set_defaults(func=build_venv)

    return parser


def main():
    parser = get_parser()
    args = parser.parse_args()

    if not hasattr(args, "func"):
        parser.print_help()
        return

    kwargs = dict(vars(args))
    del kwargs["func"]

    args.func(**kwargs)
