#!/usr/bin/env python

import argparse
import sys
import os

from subprocess import call

SCRIPTS_DIR = os.path.dirname(os.path.realpath(__file__))
PROJECTS_DIR = os.path.join(SCRIPTS_DIR, "projects")
DEFAULT_LLVM_DIR = os.path.realpath(os.path.join(SCRIPTS_DIR,
                                                 os.path.pardir,
                                                 os.path.pardir,
                                                 os.path.pardir))


def add(parser, args):
    import SATestAdd
    from ProjectMap import ProjectInfo

    if args.source == "git" and (args.origin == "" or args.commit == ""):
        parser.error(
            "Please provide both --origin and --commit if source is 'git'")

    if args.source != "git" and (args.origin != "" or args.commit != ""):
        parser.error("Options --origin and --commit don't make sense when "
                     "source is not 'git'")

    project = ProjectInfo(args.name[0], args.mode, args.source, args.origin,
                          args.commit)

    SATestAdd.add_new_project(project)


def build(parser, args):
    import SATestBuild

    SATestBuild.VERBOSE = args.verbose

    projects = get_projects(parser, args)
    tester = SATestBuild.RegressionTester(args.jobs,
                                          projects,
                                          args.override_compiler,
                                          args.extra_analyzer_config,
                                          args.regenerate,
                                          args.strictness)
    tests_passed = tester.test_all()

    if not tests_passed:
        sys.stderr.write("ERROR: Tests failed.\n")
        sys.exit(42)


def compare(parser, args):
    import CmpRuns

    choices = [CmpRuns.HistogramType.RELATIVE.value,
               CmpRuns.HistogramType.LOG_RELATIVE.value,
               CmpRuns.HistogramType.ABSOLUTE.value]

    if args.histogram is not None and args.histogram not in choices:
        parser.error("Incorrect histogram type, available choices are {}"
                     .format(choices))

    dir_old = CmpRuns.ResultsDirectory(args.old[0], args.root_old)
    dir_new = CmpRuns.ResultsDirectory(args.new[0], args.root_new)

    CmpRuns.dump_scan_build_results_diff(dir_old, dir_new,
                                         show_stats=args.show_stats,
                                         stats_only=args.stats_only,
                                         histogram=args.histogram,
                                         verbose_log=args.verbose_log)


def update(parser, args):
    import SATestUpdateDiffs
    from ProjectMap import ProjectMap

    project_map = ProjectMap()
    for project in project_map.projects:
        SATestUpdateDiffs.update_reference_results(project, args.git)


def benchmark(parser, args):
    from SATestBenchmark import Benchmark

    projects = get_projects(parser, args)
    benchmark = Benchmark(projects, args.iterations, args.output)
    benchmark.run()


def benchmark_compare(parser, args):
    import SATestBenchmark
    SATestBenchmark.compare(args.old, args.new, args.output)


def get_projects(parser, args):
    from ProjectMap import ProjectMap, Size

    project_map = ProjectMap()
    projects = project_map.projects

    def filter_projects(projects, predicate, force=False):
        return [project.with_fields(enabled=(force or project.enabled) and
                                    predicate(project))
                for project in projects]

    if args.projects:
        projects_arg = args.projects.split(",")
        available_projects = [project.name
                              for project in projects]

        # validate that given projects are present in the project map file
        for manual_project in projects_arg:
            if manual_project not in available_projects:
                parser.error("Project '{project}' is not found in "
                             "the project map file. Available projects are "
                             "{all}.".format(project=manual_project,
                                             all=available_projects))

        projects = filter_projects(projects, lambda project:
                                   project.name in projects_arg,
                                   force=True)

    try:
        max_size = Size.from_str(args.max_size)
    except ValueError as e:
        parser.error("{}".format(e))

    projects = filter_projects(projects, lambda project:
                               project.size <= max_size)

    return projects


def docker(parser, args):
    if len(args.rest) > 0:
        if args.rest[0] != "--":
            parser.error("REST arguments should start with '--'")
        args.rest = args.rest[1:]

    if args.build_image:
        docker_build_image()
    elif args.shell:
        docker_shell(args)
    else:
        sys.exit(docker_run(args, ' '.join(args.rest)))


def docker_build_image():
    sys.exit(call("docker build --tag satest-image {}".format(SCRIPTS_DIR),
                  shell=True))


def docker_shell(args):
    try:
        # First we need to start the docker container in a waiting mode,
        # so it doesn't do anything, but most importantly keeps working
        # while the shell session is in progress.
        docker_run(args, "--wait", "--detach")
        # Since the docker container is running, we can actually connect to it
        call("docker exec -it satest bash", shell=True)

    except KeyboardInterrupt:
        pass

    finally:
        docker_cleanup()


def docker_run(args, command, docker_args=""):
    try:
        return call("docker run --rm --name satest "
                    "-v {llvm}:/llvm-project "
                    "-v {build}:/build "
                    "-v {clang}:/analyzer "
                    "-v {scripts}:/scripts "
                    "-v {projects}:/projects "
                    "{docker_args} "
                    "satest-image:latest {command}"
                    .format(llvm=args.llvm_project_dir,
                            build=args.build_dir,
                            clang=args.clang_dir,
                            scripts=SCRIPTS_DIR,
                            projects=PROJECTS_DIR,
                            docker_args=docker_args,
                            command=command),
                    shell=True)

    except KeyboardInterrupt:
        docker_cleanup()


def docker_cleanup():
    print("Please wait for docker to clean up")
    call("docker stop satest", shell=True)


def main():
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers()

    # add subcommand
    add_parser = subparsers.add_parser(
        "add",
        help="Add a new project for the analyzer testing.")
    # TODO: Add an option not to build.
    # TODO: Set the path to the Repository directory.
    add_parser.add_argument("name", nargs=1, help="Name of the new project")
    add_parser.add_argument("--mode", action="store", default=1, type=int,
                            choices=[0, 1, 2],
                            help="Build mode: 0 for single file project, "
                            "1 for scan_build, "
                            "2 for single file c++11 project")
    add_parser.add_argument("--source", action="store", default="script",
                            choices=["script", "git", "zip"],
                            help="Source type of the new project: "
                            "'git' for getting from git "
                            "(please provide --origin and --commit), "
                            "'zip' for unpacking source from a zip file, "
                            "'script' for downloading source by running "
                            "a custom script")
    add_parser.add_argument("--origin", action="store", default="",
                            help="Origin link for a git repository")
    add_parser.add_argument("--commit", action="store", default="",
                            help="Git hash for a commit to checkout")
    add_parser.set_defaults(func=add)

    # build subcommand
    build_parser = subparsers.add_parser(
        "build",
        help="Build projects from the project map and compare results with "
        "the reference.")
    build_parser.add_argument("--strictness", dest="strictness",
                              type=int, default=0,
                              help="0 to fail on runtime errors, 1 to fail "
                              "when the number of found bugs are different "
                              "from the reference, 2 to fail on any "
                              "difference from the reference. Default is 0.")
    build_parser.add_argument("-r", dest="regenerate", action="store_true",
                              default=False,
                              help="Regenerate reference output.")
    build_parser.add_argument("--override-compiler", action="store_true",
                              default=False, help="Call scan-build with "
                              "--override-compiler option.")
    build_parser.add_argument("-j", "--jobs", dest="jobs",
                              type=int, default=0,
                              help="Number of projects to test concurrently")
    build_parser.add_argument("--extra-analyzer-config",
                              dest="extra_analyzer_config", type=str,
                              default="",
                              help="Arguments passed to to -analyzer-config")
    build_parser.add_argument("--projects", action="store", default="",
                              help="Comma-separated list of projects to test")
    build_parser.add_argument("--max-size", action="store", default=None,
                              help="Maximum size for the projects to test")
    build_parser.add_argument("-v", "--verbose", action="count", default=0)
    build_parser.set_defaults(func=build)

    # compare subcommand
    cmp_parser = subparsers.add_parser(
        "compare",
        help="Comparing two static analyzer runs in terms of "
        "reported warnings and execution time statistics.")
    cmp_parser.add_argument("--root-old", dest="root_old",
                            help="Prefix to ignore on source files for "
                            "OLD directory",
                            action="store", type=str, default="")
    cmp_parser.add_argument("--root-new", dest="root_new",
                            help="Prefix to ignore on source files for "
                            "NEW directory",
                            action="store", type=str, default="")
    cmp_parser.add_argument("--verbose-log", dest="verbose_log",
                            help="Write additional information to LOG "
                            "[default=None]",
                            action="store", type=str, default=None,
                            metavar="LOG")
    cmp_parser.add_argument("--stats-only", action="store_true",
                            dest="stats_only", default=False,
                            help="Only show statistics on reports")
    cmp_parser.add_argument("--show-stats", action="store_true",
                            dest="show_stats", default=False,
                            help="Show change in statistics")
    cmp_parser.add_argument("--histogram", action="store", default=None,
                            help="Show histogram of paths differences. "
                            "Requires matplotlib")
    cmp_parser.add_argument("old", nargs=1, help="Directory with old results")
    cmp_parser.add_argument("new", nargs=1, help="Directory with new results")
    cmp_parser.set_defaults(func=compare)

    # update subcommand
    upd_parser = subparsers.add_parser(
        "update",
        help="Update static analyzer reference results based on the previous "
        "run of SATest build. Assumes that SATest build was just run.")
    upd_parser.add_argument("--git", action="store_true",
                            help="Stage updated results using git.")
    upd_parser.set_defaults(func=update)

    # docker subcommand
    dock_parser = subparsers.add_parser(
        "docker",
        help="Run regression system in the docker.")

    dock_parser.add_argument("--build-image", action="store_true",
                             help="Build docker image for running tests.")
    dock_parser.add_argument("--shell", action="store_true",
                             help="Start a shell on docker.")
    dock_parser.add_argument("--llvm-project-dir", action="store",
                             default=DEFAULT_LLVM_DIR,
                             help="Path to LLVM source code. Defaults "
                             "to the repo where this script is located. ")
    dock_parser.add_argument("--build-dir", action="store", default="",
                             help="Path to a directory where docker should "
                             "build LLVM code.")
    dock_parser.add_argument("--clang-dir", action="store", default="",
                             help="Path to find/install LLVM installation.")
    dock_parser.add_argument("rest", nargs=argparse.REMAINDER, default=[],
                             help="Additionall args that will be forwarded "
                             "to the docker's entrypoint.")
    dock_parser.set_defaults(func=docker)

    # benchmark subcommand
    bench_parser = subparsers.add_parser(
        "benchmark",
        help="Run benchmarks by building a set of projects multiple times.")

    bench_parser.add_argument("-i", "--iterations", action="store",
                              type=int, default=20,
                              help="Number of iterations for building each "
                              "project.")
    bench_parser.add_argument("-o", "--output", action="store",
                              default="benchmark.csv",
                              help="Output csv file for the benchmark results")
    bench_parser.add_argument("--projects", action="store", default="",
                              help="Comma-separated list of projects to test")
    bench_parser.add_argument("--max-size", action="store", default=None,
                              help="Maximum size for the projects to test")
    bench_parser.set_defaults(func=benchmark)

    bench_subparsers = bench_parser.add_subparsers()
    bench_compare_parser = bench_subparsers.add_parser(
        "compare",
        help="Compare benchmark runs.")
    bench_compare_parser.add_argument("--old", action="store", required=True,
                                      help="Benchmark reference results to "
                                      "compare agains.")
    bench_compare_parser.add_argument("--new", action="store", required=True,
                                      help="New benchmark results to check.")
    bench_compare_parser.add_argument("-o", "--output",
                                      action="store", required=True,
                                      help="Output file for plots.")
    bench_compare_parser.set_defaults(func=benchmark_compare)

    args = parser.parse_args()
    args.func(parser, args)


if __name__ == "__main__":
    main()
