"""
aicontract Adversarial Test Suite
4 asamalı test: Kolay -> Orta -> Zor -> Brutal

Bu testler aracımızı kandırmaya calisir.
"""

import sys
import os

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from aicontract.utils.inline import check


def run_test(name, code, required_rules=None, forbidden_rules=None, verbose=True):
    """Test calistir ve sonucu goster."""
    result = check(code)

    found_rules = [v.rule_id for v in result.violations]

    if required_rules is None:
        required_rules = []
    if forbidden_rules is None:
        forbidden_rules = []

    missing = set(required_rules) - set(found_rules)
    forbidden = set(found_rules) & set(forbidden_rules)

    status = "[PASS]" if not missing and not forbidden else "[FAIL]"

    if verbose:
        print(f"\n{'=' * 60}")
        print(f"TEST: {name}")
        print(f"{'=' * 60}")
        print(f"Kod: {code[:60]}...")
        print(f"\nGerekli: {required_rules or 'None'}")
        print(f"Yasak:   {forbidden_rules or 'None'}")
        print(f"Bulunan: {found_rules}")
        if missing:
            print(f"Eksik:   {missing}")
        if forbidden:
            print(f"Yasak:   {forbidden}")
        print(
            f"\nSkor: {result.suspicion['total']} | Seviye: {result.suspicion['level']}"
        )
        print(f"Status: {status}")

    return {
        "name": name,
        "required": required_rules,
        "forbidden": forbidden_rules,
        "found": found_rules,
        "missing": missing,
        "forbidden_found": forbidden,
        "score": result.suspicion["total"],
        "level": result.suspicion["level"],
        "passed": not missing and not forbidden,
    }


print("\n" + "=" * 70)
print("TEST SUITE: aicontract ADVERSARIAL")
print("=" * 70)

results = []

# ======================================================================
# TEST 1: KOLAY (Easy) - Temel fonksiyonalite
# ======================================================================

print("\n\n" + "=" * 30)
print("TEST 1: KOLAY")
print("=" * 30)

# 1.1: Clean kod - sadece ARCH004 ve STYLE001 normal
results.append(
    run_test(
        "1.1 Clean kod",
        '''def merhaba():
    """Selam verir."""
    return "selam"
''',
        required_rules=[],
        forbidden_rules=["DEAD001", "IMP001", "SEC001", "PERF001"],
    )
)

# 1.2: Dead code - DEAD001 olmali
results.append(
    run_test(
        "1.2 Dead code (simple return)",
        """def test():
    return 1
    x = 2
""",
        required_rules=["DEAD001"],
    )
)

# 1.3: Duplicate import - IMP001 olmali
results.append(
    run_test(
        "1.3 Duplicate import",
        """import os
import os

def test():
    pass
""",
        required_rules=["IMP001"],
    )
)

# 1.4: God function - ARCH001 olmali (40+ satir)
results.append(
    run_test(
        "1.4 God function",
        """def devasa_fonksiyon():
    a = 1
    b = 2
    c = 3
    d = 4
    e = 5
    f = 6
    g = 7
    h = 8
    i = 9
    j = 10
    k = 11
    l = 12
    m = 13
    n = 14
    o = 15
    p = 16
    q = 17
    r = 18
    s = 19
    t = 20
    u = 21
    v = 22
    w = 23
    x = 24
    y = 25
    z = 26
    aa = 27
    bb = 28
    cc = 29
    dd = 30
    ee = 31
    ff = 32
    gg = 33
    hh = 34
    ii = 35
    jj = 36
    kk = 37
    ll = 38
    return a + b
""",
        required_rules=["ARCH001"],
    )
)

# ======================================================================
# TEST 2: ORTA (Medium) - Multi-rule
# ======================================================================

print("\n\n" + "=" * 30)
print("TEST 2: ORTA")
print("=" * 30)

# 2.1: IMP001 + type hint yok
results.append(
    run_test(
        "2.1 IMP001 + type hint yok",
        """import json
import json

def veri_isle(data):
    return data
""",
        required_rules=["IMP001", "ARCH004"],
    )
)

# 2.2: PERF001 + AI005 (N+1 query)
results.append(
    run_test(
        "2.2 PERF001 + AI005",
        """def verileri_isle(items):
    for item in items:
        db.execute(f"INSERT INTO t VALUES ({item})")
    return items
""",
        required_rules=["PERF001", "AI005"],
    )
)

# ======================================================================
# TEST 3: ZOR (Hard) - Edge Cases
# ======================================================================

print("\n\n" + "=" * 30)
print("TEST 3: ZOR - Edge Cases")
print("=" * 30)

# 3.1: Kosumlu return (reachable olmali - yasak)
results.append(
    run_test(
        "3.1 Kosumlu return",
        """def kosullu():
    if True:
        return 1
    return 2
""",
        forbidden_rules=["DEAD001"],
    )
)

# 3.2: Loop icinde dead code - DEAD001 olmali
results.append(
    run_test(
        "3.2 Loop + continue + dead",
        """def nested():
    for i in range(10):
        if i > 5:
            return i
        continue
        x = 1
    return -1
""",
        required_rules=["DEAD001"],
    )
)

# 3.3: Finally'de return (reachable - yasak)
results.append(
    run_test(
        "3.3 Finally'de return",
        """def finally_return():
    try:
        return 1
    finally:
        return 2
""",
        forbidden_rules=["DEAD001"],
    )
)

# 3.4: Return sonrasi raise - DEAD001 olmali
results.append(
    run_test(
        "3.4 Return + raise",
        """def ret_raise():
    return 1
    raise Exception("dead")
""",
        required_rules=["DEAD001"],
    )
)

# 3.5: Multi-line - DEAD001 olmali
results.append(
    run_test(
        "3.5 Multi-line return",
        """def multi_line():
    return \\
        1
    x = 2
""",
        required_rules=["DEAD001"],
    )
)

# 3.6: Exception handler'dan sonra - DEAD001 olmali
results.append(
    run_test(
        "3.6 Except'ten sonra unreachable",
        """def exc_handler():
    try:
        x = 1
    except:
        return 1
    return 2
    y = 3
""",
        required_rules=["DEAD001"],
    )
)

# 3.7: Silent pass (if False) - yasak
results.append(
    run_test(
        "3.7 If False (dead code degil!)",
        """def silent_pass():
    if False:
        x = 1
    return 0
""",
        forbidden_rules=["DEAD001"],
    )
)

# ======================================================================
# TEST 4: BRUTAL (Adversarial) - Kandirmaya Calis
# ======================================================================

print("\n\n" + "=" * 30)
print("TEST 4: BRUTAL - Adversarial")
print("=" * 30)

# 4.1: Exec/dynamic code - yasak
results.append(
    run_test(
        "4.1 Dynamic exec",
        """def dynamic():
    exec("return 1")
    x = 2
""",
        forbidden_rules=["DEAD001"],
    )
)

# 4.2: __future__ - AI007 yasak (var ama import yok)
results.append(
    run_test(
        "4.2 Future annotations",
        """from __future__ import annotations

def tip_hints(x: list) -> dict:
    return {}
""",
        forbidden_rules=["AI007"],  # __future__ ile kapaniyor
    )
)

# 4.3: Nested conditionals - ARCH002 + ARCH003 olmali
results.append(
    run_test(
        "4.3 Nested conditionals",
        """def nested_if(a, b, c, d, e, f):
    if a:
        if b:
            if c:
                if d:
                    if e:
                        if f:
                            return 1
    return 0
""",
        required_rules=["ARCH002", "ARCH003"],
    )
)

# 4.4: SQL injection - SEC002 olmali
results.append(
    run_test(
        "4.4 SQL injection",
        """def sql_injection(user_input):
    db.execute(f"SELECT * FROM users WHERE id = {user_input}")
    return True
""",
        required_rules=["SEC002"],
    )
)

# 4.5: Hardcoded secret - SEC001 olmali
results.append(
    run_test(
        "4.5 Hardcoded secret",
        """def connect():
    password = "super_secret_123"
    api_key = "sk-abc123xyz"
    return password
""",
        required_rules=["SEC001"],
    )
)

# 4.6: Bare exception - PERF003 olmali
results.append(
    run_test(
        "4.6 Bare exception",
        """def bare_exc():
    try:
        x = 1
    except:
        y = 2
""",
        required_rules=["PERF003"],
    )
)

# 4.7: Happy path only - AI002 olmali
results.append(
    run_test(
        "4.7 Happy path only",
        """def happy_path(data):
    return data["key"]["nested"]["value"]
""",
        required_rules=["AI002"],
    )
)

# 4.8: N+1 query - AI005 veya PERF001 olmali
results.append(
    run_test(
        "4.8 N+1 query",
        """def get_all_users():
    users = []
    for i in range(100):
        users.append(db.query(f"SELECT * FROM users WHERE id = {i}"))
    return users
""",
        required_rules=["AI005"],
    )
)

# ======================================================================
# OZET
# ======================================================================

print("\n\n" + "=" * 70)
print("TEST SONUCLARI OZETI")
print("=" * 70)

passed = sum(1 for r in results if r["passed"])
failed = len(results) - passed

print(f"\nToplam: {len(results)} test")
print(f"Gecen:  {passed}")
print(f"Kalan:   {failed}")

print("\n" + "-" * 70)
print("DETAYLI SONUCLAR:")
print("-" * 70)

for r in results:
    status = "[OK]" if r["passed"] else "[FAIL]"
    print(f"\n{status} {r['name']}")
    print(f"   Gerekli: {r['required'] or 'None'}")
    print(f"   Bulunan: {r['found']}")
    if r["missing"]:
        print(f"   Eksik:   {r['missing']}")
    if r["forbidden_found"]:
        print(f"   Yasak:   {r['forbidden_found']}")

# Brutal test ozel analizi
print("\n" + "=" * 70)
print("BRUTAL TEST ANALIZI")
print("=" * 70)

brutal_results = [r for r in results if r["name"].startswith("4.")]
brutal_passed = sum(1 for r in brutal_results if r["passed"])

print(f"\nBrutal testler: {len(brutal_results)}")
print(f"Gecen: {brutal_passed}")
print(f"Basarisiz: {len(brutal_results) - brutal_passed}")

print("\nARAC KANDIRILABILIR MI?")
print("-" * 70)

tricky = [r for r in results if not r["passed"]]
if tricky:
    print(f"Evet! {len(tricky)} test araci kandirmayi basardi:")
    for r in tricky:
        print(f"  - {r['name']}")
        if r["missing"]:
            print(f"    Eksik: {r['missing']}")
        if r["forbidden_found"]:
            print(f"    Yasak: {r['forbidden_found']}")
else:
    print("Hayir! Arac tum testlerden gecti!")
