import sys
import os
import json
import re

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

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()) == ["name", "platform"]
        assert is_string(g["platform"])
    else:
        assert sorted(g.keys()) == ["name"]

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"])

reply_index = sys.argv[1]
reply_dir = os.path.dirname(reply_index)

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