#!/usr/bin/env python3

from optparse import OptionParser, OptionGroup
import subprocess
import yaml
import os

def parse():
  parser = OptionParser("usage: f_regtest_driver.py [options] executable")
  parser.add_option("", "--test-name", dest="name", type="string",
                    help="name of the test")
  parser.add_option("", "--log-file", dest="log", type="string",
                    help="name of log file to be generated")
  parser.add_option("", "--trs-file", dest="trs", type="string",
                    help="name of test result file to be generated")
  parser.add_option("", "--color-tests", dest="color", type="string",
                    help="use coloured output")
  parser.add_option("", "--enable-hard-errors", dest="hardError", type="string",
                    help="use hard error result")
  parser.add_option("", "--expect-failure", dest="withFailure", type="string",
                    help="report failures as expected failures")
  return parser

def PASS(color = "yes"):
  return '\033[92mPASS\033[0m: ' if color == "yes" else 'PASS: '
def SKIP(color = "yes"):
  return '\033[94mSKIP\033[0m: ' if color == "yes" else 'SKIP: '
def FAIL(color = "yes"):
  return '\033[91mFAIL\033[0m: ' if color == "yes" else 'FAIL: '
def XFAIL(color = "yes"):
  return '\033[93mXFAIL\033[0m: ' if color == "yes" else 'XFAIL: '
def ERROR(color = "yes"):
  return '\033[95mFAIL\033[0m: ' if color == "yes" else 'ERROR: '

if __name__ == "__main__":
  parser = parse()
  (options, args) = parser.parse_args()

  if "RUN_PARALLEL" in os.environ:
    args = os.environ["RUN_PARALLEL"].split() + args
  result = subprocess.run(args, stdout = subprocess.PIPE)

  with open(options.log, "wb") as log:
    log.write(result.stdout)

  log = yaml.load(result.stdout, Loader=yaml.CLoader)

  with open(options.trs, "w") as trs:
    for suite in log:
      if isinstance(log[suite], list):
        for test in log[suite]:
          if not isinstance(test, dict) or len(test) > 1:
            raise ValueError
          label = list(test.keys())[0]
          trs.write(":test-result: ")
          test = test[label]
          if isinstance(test, str) and test == "succeed":
            trs.write("PASS")
            print(PASS(options.color) + label)
          elif isinstance(test, dict) and test["status"] == "skipped":
            trs.write("SKIP")
            print(SKIP(options.color) + label + ' (%s)' % test["reason"])
          elif isinstance(test, dict) and test["status"] == "failed" and test.get("expected", False):
            trs.write("XFAIL")
            print(XFAIL(options.color) + label + ' (%s)' % test["reason"])
          elif options.withFailure == "yes":
            trs.write("XFAIL")
            print(XFAIL(options.color) + label)
          else:
            trs.write("FAIL")
            print(FAIL(options.color) + label)
          trs.write("\n")
    if result.returncode != 0:
      trs.write(":test-result: ERROR\n")
      print(ERROR(options.color) + options.name + ' (return code: %d)' % result.returncode)
