import sys
import os
import json
import re
import argparse

if sys.version_info[0] >= 3:
    unicode = str
    long = int

def is_bool(x, val=None):
    return isinstance(x, bool) and (val is None or x == val)

def is_dict(x):
    return isinstance(x, dict)

def is_list(x):
    return isinstance(x, list)

def is_int(x, val=None):
    return (isinstance(x, int) or isinstance(x, long)) and (val is None or x == val)

def is_string(x, val=None):
    return (isinstance(x, str) or isinstance(x, unicode)) and (val is None or x == val)

def matches(s, pattern):
    return is_string(s) and bool(re.search(pattern, s))

def check_list_match(match, actual, expected, check=None, check_exception=None, missing_exception=None, extra_exception=None, allow_extra=False):
    """
    Handle the common pattern of making sure every actual item "matches" some
    item in the expected list, and that neither list has extra items after
    matching is completed.

    @param match: Callback to check if an actual item matches an expected
    item. Return True if the item matches, return False if the item doesn't
    match.
    @param actual: List of actual items to search.
    @param expected: List of expected items to match.
    @param check: Optional function to check that the actual item is valid by
    comparing it to the expected item.
    @param check_exception: Optional function that returns an argument to
    append to any exception thrown by the check function.
    @param missing_exception: Optional function that returns an argument to
    append to the exception thrown when an item is not found.
    @param extra_exception: Optional function that returns an argument to
    append to the exception thrown when an extra item is found.
    @param allow_extra: Optional parameter allowing there to be extra actual
    items after all the expected items have been found.
    """
    assert is_list(actual)
    _actual = actual[:]
    for expected_item in expected:
        found = False
        for i, actual_item in enumerate(_actual):
            if match(actual_item, expected_item):
                if check:
                    try:
                        check(actual_item, expected_item)
                    except BaseException as e:
                        if check_exception:
                            e.args += (check_exception(actual_item, expected_item),)
                        raise
                found = True
                del _actual[i]
                break
        if missing_exception:
            assert found, missing_exception(expected_item)
        else:
            assert found
    if not allow_extra:
        if extra_exception:
            assert len(_actual) == 0, [extra_exception(a) for a in _actual]
        else:
            assert len(_actual) == 0

def filter_list(f, l):
    if l is not None:
        l = list(filter(f, l))
    if l == []:
        l = None
    return l

def check_cmake(cmake):
    assert is_dict(cmake)
    assert sorted(cmake.keys()) == ["generator", "paths", "version"]
    check_cmake_version(cmake["version"])
    check_cmake_paths(cmake["paths"])
    check_cmake_generator(cmake["generator"])

def check_cmake_version(v):
    assert is_dict(v)
    assert sorted(v.keys()) == ["isDirty", "major", "minor", "patch", "string", "suffix"]
    assert is_string(v["string"])
    assert is_int(v["major"])
    assert is_int(v["minor"])
    assert is_int(v["patch"])
    assert is_string(v["suffix"])
    assert is_bool(v["isDirty"])

def check_cmake_paths(v):
    assert is_dict(v)
    assert sorted(v.keys()) == ["cmake", "cpack", "ctest", "root"]
    assert is_string(v["cmake"])
    assert is_string(v["cpack"])
    assert is_string(v["ctest"])
    assert is_string(v["root"])

def check_cmake_generator(g):
    assert is_dict(g)
    name = g.get("name", None)
    assert is_string(name)
    if name.startswith("Visual Studio"):
        assert sorted(g.keys()) == ["multiConfig", "name", "platform"]
        assert is_string(g["platform"])
    else:
        assert sorted(g.keys()) == ["multiConfig", "name"]
    assert is_bool(g["multiConfig"], matches(name, "^(Visual Studio |Xcode$|Ninja Multi-Config$)"))

def check_index_object(indexEntry, kind, major, minor, check):
    assert is_dict(indexEntry)
    assert sorted(indexEntry.keys()) == ["jsonFile", "kind", "version"]
    assert is_string(indexEntry["kind"])
    assert indexEntry["kind"] == kind
    assert is_dict(indexEntry["version"])
    assert sorted(indexEntry["version"].keys()) == ["major", "minor"]
    assert indexEntry["version"]["major"] == major
    assert indexEntry["version"]["minor"] == minor
    assert is_string(indexEntry["jsonFile"])
    filepath = os.path.join(reply_dir, indexEntry["jsonFile"])
    with open(filepath) as f:
        object = json.load(f)
    assert is_dict(object)
    assert "kind" in object
    assert is_string(object["kind"])
    assert object["kind"] == kind
    assert "version" in object
    assert is_dict(object["version"])
    assert sorted(object["version"].keys()) == ["major", "minor"]
    assert object["version"]["major"] == major
    assert object["version"]["minor"] == minor
    if check:
        check(object)

def check_index__test(indexEntry, major, minor):
    def check(object):
        assert sorted(object.keys()) == ["kind", "version"]
    check_index_object(indexEntry, "__test", major, minor, check)

def check_error(value, error):
    assert is_dict(value)
    assert sorted(value.keys()) == ["error"]
    assert is_string(value["error"])
    assert value["error"] == error

def check_error_re(value, error):
    assert is_dict(value)
    assert sorted(value.keys()) == ["error"]
    assert is_string(value["error"])
    assert re.search(error, value["error"])

parser = argparse.ArgumentParser()
parser.add_argument("--build-dir")
parser.add_argument("--reply-index")
parser.add_argument("--cxx-compiler-id")
parser.add_argument("--cxx-simulate-id")
args = parser.parse_args()

reply_dir = os.path.dirname(args.reply_index)

with open(args.reply_index) as f:
    index = json.load(f)
