#!/usr/bin/env python -u
import os
import sys
import getopt
import argparse
import re
import logging
import json

logger = logging.getLogger()
handler = logging.StreamHandler(sys.stdout)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.setLevel(logging.INFO)
logger.addHandler(handler)

def iter_dir_recusive(path, callback):
    if os.path.isfile(path) and os.path.splitext(path)[1] == '.js':
        logger.info("Processing {} ...".format(path))
        callback(path)
    else:
        for root, dirs, files in os.walk(path):
            for name in files:
                iter_dir_recusive(os.path.join(root, name), callback)
        logger.info("Done.")
    

class JSCTestModifier(object):
    variables = [
        "$hostOs", "$model", "$architecture"
    ]
    def __init__(self, test_pathes, conditions={}, match="all"):
        self._conditions = conditions
        self._test_pathes = test_pathes
        self._match = match
        self._skip_line_postfix = "# added by mark-jsc-stress-test.py"

    def skip(self):
        for path in self._test_pathes:
            logger.info("Mark {} skip".format(path))
            iter_dir_recusive(path, lambda file_path: self._skip_test_file(file_path))
    
    def enable(self):
        for path in self._test_pathes:
            logger.info("Mark {} enable".format(path))
            iter_dir_recusive(path, lambda file_path: self._enable_test_file(file_path))

    def _generate_condition_op(self, value):
        op = "=="
        if ("!" == value[0]):
            op = "!="
            value = value[1:]
        return op, value

    # Condition grammer is like !A or B or C and D
    # Translate it to ruby: $hostOs != A or $hostOs == B or $hostOs == C and $hostOs == D 
    def _parse_condition(self, variable, condition):
        res = []
        values = []
        for word in re.split(r'\s+', condition):
            if word == "or" or word == "and":
                value = " ".join(values).strip()
                values = []
                res.append('{} {} "{}"'.format(variable, *self._generate_condition_op(value)))
                res.append(word)
            else:
                values.append(word)
        if values:
            value = " ".join(values).strip()
            res.append('{} {} "{}"'.format(variable, *self._generate_condition_op(value)))
        return " ".join(res)

    def _generate_skip_annotation_line(self):
        skip_line_prefix = "//@ skip if"
        skip_conditions = []
        skip_line = "{} {} {}"
        supported_variables = [variable for variable in JSCTestModifier.variables if variable in self._conditions]
        condition_template = "{}" if len(supported_variables) == 1 else "({})"
        for variable in supported_variables:
            skip_conditions.append(condition_template.format(self._parse_condition(variable, self._conditions[variable])))
        if not skip_conditions:
            # No conditions, always skip 
            skip_conditions = ["true"]
        if self._match == "any":
            skip_line = skip_line.format(skip_line_prefix, " or ".join(skip_conditions), self._skip_line_postfix)
        elif self._match == "all":
            skip_line = skip_line.format(skip_line_prefix, " and ".join(skip_conditions), self._skip_line_postfix)
        return skip_line

    # This can only remove the skip annotation generated by this script
    def _enable_test_file(self, test_file):
        with open(test_file, 'r+') as f:
            lines = f.readlines()
            f.seek(0)
            for line in lines:
                if not self._skip_line_postfix in line:
                    f.write(line)
            f.truncate()
            

    def _skip_test_file(self, test_file):
        # remove the exisiting skip line, so that we can apply the new one
        self._enable_test_file(test_file)
        skip_line = self._generate_skip_annotation_line()
        with open(test_file, 'r+') as f:
            original_content = f.read()
            f.seek(0)
            f.write("{}\n{}".format(skip_line, original_content))

opensource_root = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../")
jsc_test_search_path = [
    os.path.join(opensource_root, "JSTests"), 
    os.path.join(opensource_root, "LayoutTests")
]
def main():
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(dest="action")
    file_list_help = "Files/directories list; use ',' to separate each item. Example: a.js, b.js, c.js Use '-' if you are using --jsc-json-output argument"
    parser_enable = subparsers.add_parser("enable", help="Enable the tests which are marked as skipped by this script")
    parser_enable.add_argument("files", help=file_list_help)
    parser_enable.add_argument("--jsc-json-output", help="Pass the json output of run-javascriptcore-tests to unskip all failed tests")

    parser_skip = subparsers.add_parser("skip", help="Insert skip condition to given files/directories")
    parser_skip.add_argument("files", help=file_list_help)
    parser_skip.add_argument("--jsc-json-output", help="Pass the json output of run-javascriptcore-tests to skip all failed tests")
    parser_skip.add_argument("--platform", "--host-os", help="Skip if host os matches given value, Examples: 'windows or linux' '!windows and !linux'")
    parser_skip.add_argument("--model", help="Skip if hardware model matches given value, Examples: 'Apple Watch Series 3 or Apple Watch Series 4' '!Apple Watch Series 3 and !Apple Watch Series 4'")
    parser_skip.add_argument("--architecture", help="Skip if architecture matches given value, Examples: 'arm or x86' '!arm and !x86'")
    parser_skip.add_argument("--match", default="all", help="Match all or any above conditions")
    
    args = vars(parser.parse_args())
    conditions = {}
    files = []
    if not args["files"] and not args["--log-file"]:
        logger.error("Please speicify a list of file, or use --log-file to give a JSC test log")
        return 1
    if args["files"] and not args["files"] == "-":
        files += args["files"].split(",")
    if args["jsc_json_output"]:
        with open(args["jsc_json_output"]) as f:
            jsc_json_output = json.load(f)
        failures = jsc_json_output["stressTestFailures"]
        failure_test_files_set = set()
        for failure_test in failures:
            path_parts = failure_test.split(os.path.sep)
            if 'yaml' in path_parts[0]:
                failure_test_path = os.path.join(*path_parts[1:])
            else:
                failure_test_path = failure_test
            failure_test_file = os.path.splitext(failure_test_path)[0]
            for search_path in jsc_test_search_path:
                whole_path = os.path.join(search_path, failure_test_file)
                if failure_test_file not in failure_test_files_set and os.path.isfile(whole_path):
                    files.append(whole_path)
                    failure_test_files_set.add(failure_test_file)

    if "host_os" in args and args["host_os"]:
        conditions["$hostOs"] = args["host_os"]
    if "platform" in args and args["platform"]:
        conditions["$hostOs"] = args["platform"]
    if "architecture" in args and args["architecture"]:
        conditions["$architecture"] = args["architecture"]
    if "model" in args and args["model"]:
        conditions["$model"] = args["model"]

    modifer = JSCTestModifier(files, conditions, args["match"] if "match" in args else None)
    getattr(modifer, args["action"])()
    return 0

if __name__ == '__main__':
    sys.exit(main())
