#! /usr/bin/env python

import argparse
import shutil
import subprocess
import sys
import os

from oclintscripts import cmake
from oclintscripts import environment
from oclintscripts import path
from oclintscripts import process

OCLINT_MODULES = ['core', 'metrics', 'rules', 'reporters', 'driver']

arg_parser = argparse.ArgumentParser()
arg_parser.add_argument('module_name', nargs='?', choices=['all'] + OCLINT_MODULES, default='all')
arg_parser.add_argument('-show', '--show', action="store_true")
arg_parser.add_argument('-clean', '--clean', action="store_true")
arg_parser.add_argument('-j', type=int, default=0)
arg_parser.add_argument('-use-system-compiler', '--use-system-compiler', action="store_true", default=environment.is_linux())
arg_parser.add_argument('-as-dep', '--as-dep', action="store_true")
arg_parser.add_argument('-no-ninja', '--no-ninja', action='store_true')
args = arg_parser.parse_args()

def clean_module(module_name):
    test_path = path.oclint_module_test_dir(module_name)
    path.rm_f(test_path);

def build_command(module_extras, no_ninja, source_path):
    cmd_build = cmake.builder(source_path).test_build()
    if args.as_dep:
        cmd_build = cmake.builder(source_path)
    if not no_ninja:
        cmd_build.use_ninja()
    if environment.is_unix() and not args.use_system_compiler:
        cmd_build.use_local_clang_compiler()
    extras = {'LLVM_ROOT': path.build.clang_install_dir, 'GOOGLETEST_SRC': path.source.googletest_dir, 'GOOGLETEST_BUILD': path.build.googletest_build_dir}
    extras.update(module_extras)
    return cmd_build.append_dict(extras).str()

def test_result_path(module_name):
    return os.path.join(path.oclint_module_test_dir(module_name), 'testresults.txt')

def display_test_result(module_name):
    testresult_path = test_result_path(module_name)
    with open(testresult_path, 'r') as testresult_file:
        print(testresult_file.read())

def test_module(module_name, no_ninja, j):
    build_path = path.oclint_module_test_dir(module_name)
    source_path = path.oclint_module_source_dir(module_name)

    module_extras = {}
    if module_name == "rules" or module_name == "reporters" or module_name == "driver":
        module_extras['OCLINT_SOURCE_DIR'] = path.source.core_dir
        module_extras['OCLINT_BUILD_DIR'] = path.build.core_test_dir
    if module_name == "rules":
        module_extras['OCLINT_METRICS_SOURCE_DIR'] = path.source.metrics_dir
        module_extras['OCLINT_METRICS_BUILD_DIR'] = path.build.metrics_test_dir

    command = build_command(module_extras, no_ninja, source_path)

    current_dir = os.getcwd()
    path.mkdir_p(build_path)
    path.cd(build_path)
    process.call(command)
    if no_ninja:
        process.make(j)
    else:
        process.ninja(j)
    if not args.as_dep:
        run_ctest_command = 'ctest --output-on-failure > ' + test_result_path(module_name)
        ctest_exit_code = subprocess.call(run_ctest_command, shell=True)
        display_test_result(module_name)
        if ctest_exit_code:
            sys.exit(ctest_exit_code)
    path.cd(current_dir)

build_modules = []
if args.module_name == 'all':
    build_modules.extend(OCLINT_MODULES)
else:
    build_modules.append(args.module_name)

if args.show:
    for module in build_modules:
        display_test_result(module)
    sys.exit(0)

if args.clean:
    for module in build_modules:
        clean_module(module)

for module in build_modules:
    test_module(module, args.no_ninja, args.j)
