import ast
from typing import Any

from resp_type import all_type

def check_true(value):
    false_vals = ["false", "not", "no", "0"]
    for f in false_vals:
        if f in value.lower():
            return 0
    true_vals = ["found", "true", "yes", "1", "correct", "right", "match"]
    for t in true_vals:
        if t in value.lower():
            return 1
    return 0.5

class CategoryToBool(ast.NodeTransformer):
    def visit_Assert(self, node: ast.Assert) -> Any:
        value = node.test.comparators[0]
        if isinstance(value, ast.Constant) and isinstance(value.value, bool):
            return node
        if isinstance(value, ast.Constant) and isinstance(value.value, str):
            try: # test if string is number
                ast.Constant(value=int(value.value))
            except:
                val_check = check_true(value.value)
                if val_check == 0.5:
                    return node
                value = ast.Constant(value=True if val_check==1 else False)
        node.test.comparators[0] = value
        return node
 
class BoolToList(ast.NodeTransformer):
    def visit_Assert(self, node: ast.Assert) -> Any:
        value = node.test.comparators[0]
        if value.value in ["True", True]:
            node.test.comparators[0] = node.test.left.args[0]
        else:
            node.test.comparators[0] = ast.List(elts=[])
        return node


def all_bool(assertions_updated):
    seen =[a_.replace(' ', '') for a in list(assertions_updated.values())  for a_ in a]
    seen.append([])

    prev_assertions_updated = assertions_updated.copy()
    for func in [CategoryToBool, BoolToList]:
        for key, combination in prev_assertions_updated.items():
            resp=[]
            # check if assertion type is==2 and is string
            checking=[]
            for assertion in combination:
                ip = ast.parse(assertion).body[0].test.comparators
                if len(ip)==1 and isinstance(ip[0], ast.Constant):
                    checking.append(ip[0].value)
            checking = list(set(checking))
            if len(checking)==2:
                if func == BoolToList and "ip_resp-SingleStrToList" not in key:
                    continue
                for assertion in combination:
                    temp = ast.unparse(func().visit(ast.parse(assertion)))
                    if temp.replace(" ", "") not in seen:
                        seen.append(temp)
                        resp.append(temp)
                if len(resp)==len(assertions_updated["original"]) and resp not in list(assertions_updated.values()):    
                    assertions_updated[f"op_resp-{func.__name__}--{str(key).replace(" ", "")}"] = resp

    return assertions_updated

def main():
    # assertions = ["assert some_name(2,3) == (2,3)", "assert some_name(3,1) == (1,2,3)"]
    # op = all_type(assertions)
    # op = all_bool(op)
    # print(op)

    assertions = ["assert some_name(2) == 'True'", "assert some_name(3) == 'False'"]
    op = all_type(assertions)
    op = all_bool(op)
    print(op)

    # assertions = ["assert some_name(2,3) == 'Truematch'", "assert some_name(3,1) == 'Falsematch'"]
    # op = all_type(assertions)
    # op = all_bool(op)
    # print(op)
    return


if __name__ == "__main__":
    main()