#!/usr/bin/env python
# vi:syntax=python
from __future__ import print_function
import sys
import os
import subprocess
import argparse
import multiprocessing as mp


if not os.path.exists("CMakeCache.txt"):
  print("Not in CMake build dir. Not executing")
  sys.exit(1)

def check_output(*args, **kwargs):
  p = subprocess.Popen(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kwargs)
  p.wait()
  stdout, stderr = p.communicate()
  if sys.version_info > (2,):
    stdout = stdout.decode("utf-8")
  return (p.returncode, stdout.strip())

# call helper function
def call(cmd):
  print(" ".join(cmd))
  try:
    subprocess.check_call(cmd)
  except subprocess.CalledProcessError as e:
    print("Failed, output: ", e.output)
    raise e

p = argparse.ArgumentParser()
p.add_argument("--gcov", default=check_output(["which", "gcov"])[1])
args = p.parse_args()


bundled_gcovr = os.path.abspath(os.path.join(os.getcwd(), "../cmake/gcovr"))

ret, gcovr_exe = check_output(["which", "gcovr"])
if ret != 0:
  # gcovr not in path
  # bundled version needs python2
  if sys.version_info < (3,):
    # this python is v2, use it
    gcovr = [sys.executable, bundled_gcovr]
  else:
    # this is not python2, see if installed
    ret, python_exe = check_output(["which", "python2"])
    if ret == 0:
      gcovr = [python_exe, bundled_gcovr]
    else:
      # check if python executable is v2
      ret, python_exe = check_output(["which", "python"])
      if ret != 0:
        # on python3, no python2 installed but also no gcovr, nothing we can do
        print("Cannot run coverage in this configuration")
        sys.exit(1)
      ret, python_ver = check_output(["python", "--version"])
      assert ret == 0, "Error checking python version"
      import re
      version = tuple(map(int, re.match("^Python (\d\.\d\.\d)", python_ver).group(1).split(".")))
      if version > (2,):
        # version ok, use it
        gcovr = [python_exe, bundled_gcovr]
else:
  # gcovr in path, use directry
  gcovr = [gcovr_exe] # will have correct python version

script_dir = os.path.dirname(__file__)
source_dir = os.path.abspath(os.path.join(script_dir, ".."))
coverage_dir = os.path.abspath("coverage")

if not os.path.exists(coverage_dir):
  os.makedirs(coverage_dir)

excludes = ["-e", "../Tests/", "-e", "../Legacy", "-e", ".*json\.hpp"]

# create the html report
call(gcovr
     + ["-r", source_dir]
     + ["--gcov-executable", args.gcov]
     + ["-j", str(mp.cpu_count())]
     + excludes +
     ["--xml", "-o", "coverage/cov.xml"])
     #  ["--html", "--html-details",
     #  "-o", os.path.join(coverage_dir, "index.html")])

call(gcovr
     + ["-r", source_dir]
     + ["-j", str(mp.cpu_count())]
     + ["--gcov-executable", args.gcov]
     + excludes)


