import json
import os
import sys
import argparse
import subprocess
import tempfile
import shutil
import site
import pkg_resources

from molotov import __version__
from molotov.run import main as run, _parser


def clone_repo(github):
    # XXX security
    subprocess.check_call("git clone %s ." % github, shell=True)


def create_virtualenv(virtualenv, python):
    # XXX security
    subprocess.check_call("%s --python %s venv" % (virtualenv, python), shell=True)


def install_reqs(reqfile):
    subprocess.check_call("./venv/bin/pip install -r %s" % reqfile, shell=True)


def run_test(**options):
    """Runs a molotov test.
    """
    parser = _parser()
    fields = {}
    cli = []
    for action in parser._actions:
        if action.dest in ("help", "scenario"):
            continue
        op_str = action.option_strings[0]
        fields[action.dest] = op_str, action.const, type(action)

    for key, value in options.items():
        if key in fields:
            opt, const, type_ = fields[key]
            is_count = type_ is argparse._CountAction
            if const or is_count:
                if is_count:
                    cli += [opt] * value
                else:
                    cli.append(opt)
            else:
                cli.append(opt)
                cli.append(str(value))

    cli.append(options.pop("scenario", "loadtest.py"))
    args = parser.parse_args(args=cli)
    print("Running: molotov %s" % " ".join(cli))
    return run(args)


def main():
    """Moloslave clones a git repo and runs a molotov test
    """
    parser = argparse.ArgumentParser(description="Github-based load test")

    parser.add_argument(
        "--version",
        action="store_true",
        default=False,
        help="Displays version and exits.",
    )

    parser.add_argument(
        "--virtualenv", type=str, default="virtualenv", help="Virtualenv executable."
    )

    parser.add_argument(
        "--python", type=str, default=sys.executable, help="Python executable."
    )

    parser.add_argument(
        "--config",
        type=str,
        default="molotov.json",
        help="Path of the configuration file.",
    )

    parser.add_argument("repo", help="Github repo", type=str, nargs="?")
    parser.add_argument("run", help="Test to run", nargs="?")

    args = parser.parse_args()

    if args.version:
        print(__version__)
        sys.exit(0)

    tempdir = tempfile.mkdtemp()
    curdir = os.getcwd()
    os.chdir(tempdir)
    print("Working directory is %s" % tempdir)
    try:
        clone_repo(args.repo)
        config_file = os.path.join(tempdir, args.config)

        with open(config_file) as f:
            config = json.loads(f.read())

        # creating the virtualenv
        create_virtualenv(args.virtualenv, args.python)

        # install deps
        if "requirements" in config["molotov"]:
            install_reqs(config["molotov"]["requirements"])

        # load deps into sys.path
        pyver = "%d.%d" % (sys.version_info.major, sys.version_info.minor)
        site_pkg = os.path.join(
            tempdir, "venv", "lib", "python" + pyver, "site-packages"
        )
        site.addsitedir(site_pkg)
        pkg_resources.working_set.add_entry(site_pkg)

        # environment
        if "env" in config["molotov"]:
            for key, value in config["molotov"]["env"].items():
                os.environ[key] = value

        run_test(**config["molotov"]["tests"][args.run])
    except Exception:
        os.chdir(curdir)
        shutil.rmtree(tempdir, ignore_errors=True)
        raise