#SPDX-License-Identifier: GPL-2.0
import re
import csv
import json
import argparse
from pathlib import Path
import subprocess

class Validator:
    def __init__(self, rulefname, reportfname='', t=5, debug=False, datafname='', fullrulefname='', workload='true', metrics=''):
        self.rulefname = rulefname
        self.reportfname = reportfname
        self.rules = None
        self.collectlist:str = metrics
        self.metrics = self.__set_metrics(metrics)
        self.skiplist = set()
        self.tolerance = t

        self.workloads = [x for x in workload.split(",") if x]
        self.wlidx = 0 # idx of current workloads
        self.allresults = dict() # metric results of all workload
        self.allignoremetrics = dict() # metrics with no results or negative results
        self.allfailtests = dict()
        self.alltotalcnt = dict()
        self.allpassedcnt = dict()
        self.allerrlist = dict()

        self.results = dict() # metric results of current workload
        # vars for test pass/failure statistics
        self.ignoremetrics= set() # metrics with no results or negative results, neg result counts as a failed test
        self.failtests = dict()
        self.totalcnt = 0
        self.passedcnt = 0
        # vars for errors
        self.errlist = list()

        # vars for Rule Generator
        self.pctgmetrics = set() # Percentage rule

        # vars for debug
        self.datafname = datafname
        self.debug = debug
        self.fullrulefname = fullrulefname

    def __set_metrics(self, metrics=''):
        if metrics != '':
            return set(metrics.split(","))
        else:
            return set()

    def read_json(self, filename: str) -> dict:
        try:
            with open(Path(filename).resolve(), "r") as f:
                data = json.loads(f.read())
        except OSError as e:
            print(f"Error when reading file {e}")
            sys.exit()

        return data

    def json_dump(self, data, output_file):
        parent = Path(output_file).parent
        if not parent.exists():
            parent.mkdir(parents=True)

        with open(output_file, "w+") as output_file:
            json.dump(data,
                      output_file,
                      ensure_ascii=True,
                      indent=4)

    def get_results(self, idx:int = 0):
        return self.results[idx]

    def get_bounds(self, lb, ub, error, alias={}, ridx:int = 0) -> list:
        """
        Get bounds and tolerance from lb, ub, and error.
        If missing lb, use 0.0; missing ub, use float('inf); missing error, use self.tolerance.

        @param lb: str/float, lower bound
        @param ub: str/float, upper bound
        @param error: float/str, error tolerance
        @returns: lower bound, return inf if the lower bound is a metric value and is not collected
                  upper bound, return -1 if the upper bound is a metric value and is not collected
                  tolerance, denormalized base on upper bound value
        """
        # init ubv and lbv to invalid values
        def get_bound_value (bound, initval, ridx):
            val = initval
            if isinstance(bound, int) or isinstance(bound, float):
                val = bound
            elif isinstance(bound, str):
                if bound == '':
                    val = float("inf")
                elif bound in alias:
                    vall = self.get_value(alias[ub], ridx)
                    if vall:
                        val = vall[0]
                elif bound.replace('.', '1').isdigit():
                    val = float(bound)
                else:
                    print("Wrong bound: {0}".format(bound))
            else:
                print("Wrong bound: {0}".format(bound))
            return val

        ubv = get_bound_value(ub, -1, ridx)
        lbv = get_bound_value(lb, float('inf'), ridx)
        t = get_bound_value(error, self.tolerance, ridx)

        # denormalize error threshold
        denormerr = t * ubv / 100 if ubv != 100 and ubv > 0 else t

        return lbv, ubv, denormerr

    def get_value(self, name:str, ridx:int = 0) -> list:
        """
        Get value of the metric from self.results.
        If result of this metric is not provided, the metric name will be added into self.ignoremetics and self.errlist.
        All future test(s) on this metric will fail.

        @param name: name of the metric
        @returns: list with value found in self.results; list is empty when value is not found.
        """
        results = []
        data = self.results[ridx] if ridx in self.results else self.results[0]
        if name not in self.ignoremetrics:
            if name in data:
                results.append(data[name])
            elif name.replace('.', '1').isdigit():
                results.append(float(name))
            else:
                self.ignoremetrics.add(name)
        return results

    def check_bound(self, val, lb, ub, err):
        return True if val <= ub + err and val >= lb - err else False

    # Positive Value Sanity check
    def pos_val_test(self):
        """
        Check if metrics value are non-negative.
        One metric is counted as one test.
        Failure: when metric value is negative or not provided.
        Metrics with negative value will be added into the self.failtests['PositiveValueTest'] and self.ignoremetrics.
        """
        negmetric = dict()
        pcnt = 0
        tcnt = 0
        rerun = list()
        for name, val in self.get_results().items():
            if val < 0:
                negmetric[name] = val
                rerun.append(name)
            else:
                pcnt += 1
            tcnt += 1
        if len(rerun) > 0 and len(rerun) < 20:
            second_results = dict()
            self.second_test(rerun, second_results)
            for name, val in second_results.items():
                if name not in negmetric: continue
                if val >= 0:
                    del negmetric[name]
                    pcnt += 1

        self.failtests['PositiveValueTest']['Total Tests'] = tcnt
        self.failtests['PositiveValueTest']['Passed Tests'] = pcnt
        if len(negmetric.keys()):
            self.ignoremetrics.update(negmetric.keys())
            negmessage = ["{0}(={1:.4f})".format(name, val) for name, val in negmetric.items()]
            self.failtests['PositiveValueTest']['Failed Tests'].append({'NegativeValue': negmessage})

        return

    def evaluate_formula(self, formula:str, alias:dict, ridx:int = 0):
        """
        Evaluate the value of formula.

        @param formula: the formula to be evaluated
        @param alias: the dict has alias to metric name mapping
        @returns: value of the formula is success; -1 if the one or more metric value not provided
        """
        stack = []
        b = 0
        errs = []
        sign = "+"
        f = str()

        #TODO: support parenthesis?
        for i in range(len(formula)):
            if i+1 == len(formula) or formula[i] in ('+', '-', '*', '/'):
                s = alias[formula[b:i]] if i+1 < len(formula) else alias[formula[b:]]
                v = self.get_value(s, ridx)
                if not v:
                    errs.append(s)
                else:
                    f = f + "{0}(={1:.4f})".format(s, v[0])
                    if sign == "*":
                        stack[-1] = stack[-1] * v
                    elif sign == "/":
                        stack[-1] = stack[-1] / v
                    elif sign == '-':
                        stack.append(-v[0])
                    else:
                        stack.append(v[0])
                if i + 1 < len(formula):
                    sign = formula[i]
                    f += sign
                    b = i + 1

        if len(errs) > 0:
            return -1, "Metric value missing: "+','.join(errs)

        val = sum(stack)
        return val, f

    # Relationships Tests
    def relationship_test(self, rule: dict):
        """
        Validate if the metrics follow the required relationship in the rule.
        eg. lower_bound <= eval(formula)<= upper_bound
        One rule is counted as ont test.
        Failure: when one or more metric result(s) not provided, or when formula evaluated outside of upper/lower bounds.

        @param rule: dict with metric name(+alias), formula, and required upper and lower bounds.
        """
        alias = dict()
        for m in rule['Metrics']:
            alias[m['Alias']] = m['Name']
        lbv, ubv, t = self.get_bounds(rule['RangeLower'], rule['RangeUpper'], rule['ErrorThreshold'], alias, ridx=rule['RuleIndex'])
        val, f = self.evaluate_formula(rule['Formula'], alias, ridx=rule['RuleIndex'])
        if val == -1:
            self.failtests['RelationshipTest']['Failed Tests'].append({'RuleIndex': rule['RuleIndex'], 'Description':f})
        elif not self.check_bound(val, lbv, ubv, t):
            lb = rule['RangeLower']
            ub = rule['RangeUpper']
            if isinstance(lb, str):
                if lb in alias:
                    lb = alias[lb]
            if isinstance(ub, str):
                if ub in alias:
                    ub = alias[ub]
            self.failtests['RelationshipTest']['Failed Tests'].append({'RuleIndex': rule['RuleIndex'], 'Formula':f,
                                                                       'RangeLower': lb, 'LowerBoundValue': self.get_value(lb),
                                                                       'RangeUpper': ub, 'UpperBoundValue':self.get_value(ub),
                                                                       'ErrorThreshold': t, 'CollectedValue': val})
        else:
            self.passedcnt += 1
            self.failtests['RelationshipTest']['Passed Tests'] += 1
        self.totalcnt += 1
        self.failtests['RelationshipTest']['Total Tests'] += 1

        return


    # Single Metric Test
    def single_test(self, rule:dict):
        """
        Validate if the metrics are in the required value range.
        eg. lower_bound <= metrics_value <= upper_bound
        One metric is counted as one test in this type of test.
        One rule may include one or more metrics.
        Failure: when the metric value not provided or the value is outside the bounds.
        This test updates self.total_cnt and records failed tests in self.failtest['SingleMetricTest'].

        @param rule: dict with metrics to validate and the value range requirement
        """
        lbv, ubv, t = self.get_bounds(rule['RangeLower'], rule['RangeUpper'], rule['ErrorThreshold'])
        metrics = rule['Metrics']
        passcnt = 0
        totalcnt = 0
        faillist = list()
        failures = dict()
        rerun = list()
        for m in metrics:
            totalcnt += 1
            result = self.get_value(m['Name'])
            if len(result) > 0 and self.check_bound(result[0], lbv, ubv, t) or m['Name'] in self.skiplist:
                passcnt += 1
            else:
                failures[m['Name']] = result
                rerun.append(m['Name'])

        if len(rerun) > 0 and len(rerun) < 20:
            second_results = dict()
            self.second_test(rerun, second_results)
            for name, val in second_results.items():
                if name not in failures: continue
                if self.check_bound(val, lbv, ubv, t):
                    passcnt += 1
                    del failures[name]
                else:
                    failures[name] = val
                    self.results[0][name] = val

        self.totalcnt += totalcnt
        self.passedcnt += passcnt
        self.failtests['SingleMetricTest']['Total Tests'] += totalcnt
        self.failtests['SingleMetricTest']['Passed Tests'] += passcnt
        if len(failures.keys()) != 0:
            faillist = [{'MetricName':name, 'CollectedValue':val} for name, val in failures.items()]
            self.failtests['SingleMetricTest']['Failed Tests'].append({'RuleIndex':rule['RuleIndex'],
                                                                       'RangeLower': rule['RangeLower'],
                                                                       'RangeUpper': rule['RangeUpper'],
                                                                       'ErrorThreshold':rule['ErrorThreshold'],
                                                                       'Failure':faillist})

        return

    def create_report(self):
        """
        Create final report and write into a JSON file.
        """
        alldata = list()
        for i in range(0, len(self.workloads)):
            reportstas = {"Total Rule Count": self.alltotalcnt[i], "Passed Rule Count": self.allpassedcnt[i]}
            data = {"Metric Validation Statistics": reportstas, "Tests in Category": self.allfailtests[i],
                    "Errors":self.allerrlist[i]}
            alldata.append({"Workload": self.workloads[i], "Report": data})

        json_str = json.dumps(alldata, indent=4)
        print("Test validation finished. Final report: ")
        print(json_str)

        if self.debug:
            allres = [{"Workload": self.workloads[i], "Results": self.allresults[i]} for i in range(0, len(self.workloads))]
            self.json_dump(allres, self.datafname)

    def check_rule(self, testtype, metric_list):
        """
        Check if the rule uses metric(s) that not exist in current platform.

        @param metric_list: list of metrics from the rule.
        @return: False when find one metric out in Metric file. (This rule should not skipped.)
                 True when all metrics used in the rule are found in Metric file.
        """
        if testtype == "RelationshipTest":
            for m in metric_list:
                if m['Name'] not in self.metrics:
                    return False
        return True

    # Start of Collector and Converter
    def convert(self, data: list, metricvalues:dict):
        """
        Convert collected metric data from the -j output to dict of {metric_name:value}.
        """
        for json_string in data:
            try:
                result =json.loads(json_string)
                if "metric-unit" in result and result["metric-unit"] != "(null)" and result["metric-unit"] != "":
                    name = result["metric-unit"].split("  ")[1] if len(result["metric-unit"].split("  ")) > 1 \
                        else result["metric-unit"]
                    metricvalues[name.lower()] = float(result["metric-value"])
            except ValueError as error:
                continue
        return

    def _run_perf(self, metric, workload: str):
        tool = 'perf'
        command = [tool, 'stat', '-j', '-M', f"{metric}", "-a"]
        wl = workload.split()
        command.extend(wl)
        print(" ".join(command))
        cmd = subprocess.run(command, stderr=subprocess.PIPE, encoding='utf-8')
        data = [x+'}' for x in cmd.stderr.split('}\n') if x]
        return data


    def collect_perf(self, workload: str):
        """
        Collect metric data with "perf stat -M" on given workload with -a and -j.
        """
        self.results = dict()
        print(f"Starting perf collection")
        print(f"Long workload: {workload}")
        collectlist = dict()
        if self.collectlist != "":
            collectlist[0] = {x for x in self.collectlist.split(",")}
        else:
            collectlist[0] = set(list(self.metrics))
        # Create metric set for relationship rules
        for rule in self.rules:
            if rule["TestType"] == "RelationshipTest":
                metrics = [m["Name"] for m in rule["Metrics"]]
                if not any(m not in collectlist[0] for m in metrics):
                    collectlist[rule["RuleIndex"]] = [",".join(list(set(metrics)))]

        for idx, metrics in collectlist.items():
            if idx == 0: wl = "true"
            else: wl = workload
            for metric in metrics:
                data = self._run_perf(metric, wl)
                if idx not in self.results: self.results[idx] = dict()
                self.convert(data, self.results[idx])
        return

    def second_test(self, collectlist, second_results):
        workload = self.workloads[self.wlidx]
        for metric in collectlist:
            data = self._run_perf(metric, workload)
            self.convert(data, second_results)

    # End of Collector and Converter

    # Start of Rule Generator
    def parse_perf_metrics(self):
        """
        Read and parse perf metric file:
        1) find metrics with '1%' or '100%' as ScaleUnit for Percent check
        2) create metric name list
        """
        command = ['perf', 'list', '-j', '--details', 'metrics']
        cmd = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8')
        try:
            data = json.loads(cmd.stdout)
            for m in data:
                if 'MetricName' not in m:
                    print("Warning: no metric name")
                    continue
                name = m['MetricName'].lower()
                self.metrics.add(name)
                if 'ScaleUnit' in m and (m['ScaleUnit'] == '1%' or m['ScaleUnit'] == '100%'):
                    self.pctgmetrics.add(name.lower())
        except ValueError as error:
            print(f"Error when parsing metric data")
            sys.exit()

        return

    def remove_unsupported_rules(self, rules):
        new_rules = []
        for rule in rules:
            add_rule = True
            for m in rule["Metrics"]:
                if m["Name"] in self.skiplist or m["Name"] not in self.metrics:
                    add_rule = False
                    break
            if add_rule:
                new_rules.append(rule)
        return new_rules

    def create_rules(self):
        """
        Create full rules which includes:
        1) All the rules from the "relationshi_rules" file
        2) SingleMetric rule for all the 'percent' metrics

        Reindex all the rules to avoid repeated RuleIndex
        """
        data = self.read_json(self.rulefname)
        rules = data['RelationshipRules']
        self.skiplist = set([name.lower() for name in data['SkipList']])
        self.rules = self.remove_unsupported_rules(rules)
        pctgrule = {'RuleIndex':0,
                    'TestType':'SingleMetricTest',
                    'RangeLower':'0',
                    'RangeUpper': '100',
                    'ErrorThreshold': self.tolerance,
                    'Description':'Metrics in percent unit have value with in [0, 100]',
                    'Metrics': [{'Name': m.lower()} for m in self.pctgmetrics]}
        self.rules.append(pctgrule)

        # Re-index all rules to avoid repeated RuleIndex
        idx = 1
        for r in self.rules:
            r['RuleIndex'] = idx
            idx += 1

        if self.debug:
            #TODO: need to test and generate file name correctly
            data = {'RelationshipRules':self.rules, 'SupportedMetrics': [{"MetricName": name} for name in self.metrics]}
            self.json_dump(data, self.fullrulefname)

        return
    # End of Rule Generator

    def _storewldata(self, key):
        '''
        Store all the data of one workload into the corresponding data structure for all workloads.
        @param key: key to the dictionaries (index of self.workloads).
        '''
        self.allresults[key] = self.results
        self.allignoremetrics[key] = self.ignoremetrics
        self.allfailtests[key] = self.failtests
        self.alltotalcnt[key] = self.totalcnt
        self.allpassedcnt[key] = self.passedcnt
        self.allerrlist[key] = self.errlist

    #Initialize data structures before data validation of each workload
    def _init_data(self):

        testtypes = ['PositiveValueTest', 'RelationshipTest', 'SingleMetricTest']
        self.results = dict()
        self.ignoremetrics= set()
        self.errlist = list()
        self.failtests = {k:{'Total Tests':0, 'Passed Tests':0, 'Failed Tests':[]} for k in testtypes}
        self.totalcnt = 0
        self.passedcnt = 0

    def test(self):
        '''
        The real entry point of the test framework.
        This function loads the validation rule JSON file and Standard Metric file to create rules for
        testing and namemap dictionaries.
        It also reads in result JSON file for testing.

        In the test process, it passes through each rule and launch correct test function bases on the
        'TestType' field of the rule.

        The final report is written into a JSON file.
        '''
        if not self.collectlist:
            self.parse_perf_metrics()
        self.create_rules()
        for i in range(0, len(self.workloads)):
            self.wlidx = i
            self._init_data()
            self.collect_perf(self.workloads[i])
            # Run positive value test
            self.pos_val_test()
            for r in self.rules:
                # skip rules that uses metrics not exist in this platform
                testtype = r['TestType']
                if not self.check_rule(testtype, r['Metrics']):
                    continue
                if  testtype == 'RelationshipTest':
                    self.relationship_test(r)
                elif testtype == 'SingleMetricTest':
                    self.single_test(r)
                else:
                    print("Unsupported Test Type: ", testtype)
                    self.errlist.append("Unsupported Test Type from rule: " + r['RuleIndex'])
            self._storewldata(i)
            print("Workload: ", self.workloads[i])
            print("Total metrics collected: ", self.failtests['PositiveValueTest']['Total Tests'])
            print("Non-negative metric count: ", self.failtests['PositiveValueTest']['Passed Tests'])
            print("Total Test Count: ", self.totalcnt)
            print("Passed Test Count: ", self.passedcnt)

        self.create_report()
        return sum(self.alltotalcnt.values()) != sum(self.allpassedcnt.values())
# End of Class Validator


def main() -> None:
    parser = argparse.ArgumentParser(description="Launch metric value validation")

    parser.add_argument("-rule", help="Base validation rule file", required=True)
    parser.add_argument("-output_dir", help="Path for validator output file, report file", required=True)
    parser.add_argument("-debug", help="Debug run, save intermediate data to files", action="store_true", default=False)
    parser.add_argument("-wl", help="Workload to run while data collection", default="true")
    parser.add_argument("-m", help="Metric list to validate", default="")
    args = parser.parse_args()
    outpath = Path(args.output_dir)
    reportf = Path.joinpath(outpath, 'perf_report.json')
    fullrule = Path.joinpath(outpath, 'full_rule.json')
    datafile = Path.joinpath(outpath, 'perf_data.json')

    validator = Validator(args.rule, reportf, debug=args.debug,
                        datafname=datafile, fullrulefname=fullrule, workload=args.wl,
                        metrics=args.m)
    ret = validator.test()

    return ret


if __name__ == "__main__":
    import sys
    sys.exit(main())



