"""
python -m aicontract <komut>

Komutlar:
    init [dizin]          — Projeye aicontract kur
    mcp                   — MCP sunucusunu başlat (stdio)
    check [dosya/dizin]   — Analiz et
    diff                  — Git diff'teki değişiklikleri kontrol et
    learn [dizin]         — Baseline öğren
    snapshot [dizin]      — Mevcut violation'ları baseline al (only-new için)
    hotspot [dizin]       — Risk haritası
    memory list           — Mimari kararları listele
    memory add            — Karar ekle
    explain <KURAL_ID>    — Kural açıklaması
    version               — Sürüm
"""

import sys
import os


def main():
    args = sys.argv[1:]

    if not args or args[0] in ("-h", "--help", "help"):
        print(__doc__)
        return

    cmd = args[0]

    # ── mcp ───────────────────────────────────────────────────────────
    if cmd == "mcp":
        from .mcp_server import run
        run()
        return

    # ── init ──────────────────────────────────────────────────────────
    if cmd == "init":
        project_dir = args[1] if len(args) > 1 else "."
        force = "--force" in args
        from .init_cmd import init
        init(project_dir, force=force)
        return

    # ── check ─────────────────────────────────────────────────────────
    if cmd == "check":
        target = args[1] if len(args) > 1 else "."
        fmt = "terminal"
        only_new = "--only-new" in args
        for a in args:
            if a.startswith("--format="):
                fmt = a.split("=", 1)[1]

        from .inline import check as inline_check, check_file
        from .config import get_exit_code, load_config

        load_config()
        all_violations = []

        if os.path.isfile(target):
            v = check_file(target, output_format=fmt)
            all_violations.extend(v)
        else:
            skip = {"__pycache__", ".git", ".venv", "venv", "env",
                    "node_modules", "dist", "build"}
            from .config import safe_read_file, filter_violations, get_config
            from .init_cmd import get_violation_baseline
            vb = get_violation_baseline(target) if only_new else None

            for root, dirs, files in os.walk(target):
                dirs[:] = [d for d in dirs if d not in skip]
                for fname in sorted(files):
                    if not fname.endswith(".py"):
                        continue
                    fp = os.path.join(root, fname)
                    rel = os.path.relpath(fp, target)
                    src, err = safe_read_file(fp)
                    if err or not src:
                        continue
                    v = inline_check(src, silent=True, filepath=rel)
                    v = filter_violations(v, src, get_config())
                    if only_new and vb:
                        v = vb.filter_new(v, rel)
                    if v:
                        print(f"\n\033[94m{rel}\033[0m")
                        for viol in v:
                            sev = "\033[91mHATA\033[0m" if viol.severity == "error" else "\033[93mUYARI\033[0m"
                            print(f"  [{sev}] {viol.rule_id} satır {viol.line}: {viol.message}")
                            if viol.suggestion:
                                print(f"    → {viol.suggestion}")
                    all_violations.extend(v)

        if not all_violations:
            print("\033[92m✓ Temiz — ihlal bulunamadı\033[0m")

        ec = get_exit_code(all_violations)
        sys.exit(ec)

    # ── diff ──────────────────────────────────────────────────────────
    if cmd == "diff":
        project_dir = args[1] if len(args) > 1 else "."
        staged = "--staged" in args
        from .config import check_diff
        result = check_diff(project_dir, staged_only=staged)
        sys.exit(result["exit_code"])

    # ── learn ─────────────────────────────────────────────────────────
    if cmd == "learn":
        project_dir = args[1] if len(args) > 1 else "."
        incremental = "--incremental" in args
        if incremental:
            from .init_cmd import learn_incremental
            learn_incremental(project_dir)
        else:
            from .smart import learn
            learn(project_dir)
        return

    # ── snapshot ──────────────────────────────────────────────────────
    if cmd == "snapshot":
        project_dir = args[1] if len(args) > 1 else "."
        from .init_cmd import get_violation_baseline
        vb = get_violation_baseline(project_dir)
        vb.snapshot(project_dir)
        return

    # ── hotspot ───────────────────────────────────────────────────────
    if cmd == "hotspot":
        target = args[1] if len(args) > 1 else "."
        top = 5
        for a in args:
            if a.startswith("--top="):
                top = int(a.split("=", 1)[1])
        from .hotspot import hotspot
        hotspot(target, top=top)
        return

    # ── memory ────────────────────────────────────────────────────────
    if cmd == "memory":
        sub = args[1] if len(args) > 1 else "list"
        from .session_memory import SessionMemory
        mem = SessionMemory()

        if sub == "list":
            decisions = mem.list_decisions()
            if not decisions:
                print("Kayıtlı mimari karar yok.")
            else:
                print(mem.summary())
                for d in decisions:
                    flag = "ZORUNLU" if d.enforced else "tavsiye"
                    print(f"  [{d.uid}] [{d.category}] {d.rule} ({flag})")
        elif sub == "add":
            category = None
            rule = None
            reason = ""
            i = 2
            while i < len(args):
                if args[i] == "--category" and i + 1 < len(args):
                    category = args[i + 1]; i += 2
                elif args[i] == "--rule" and i + 1 < len(args):
                    rule = args[i + 1]; i += 2
                elif args[i] == "--reason" and i + 1 < len(args):
                    reason = args[i + 1]; i += 2
                else:
                    i += 1
            if category and rule:
                mem.add_decision(category, rule, reason)
            else:
                print("Kullanım: aicontract memory add --category X --rule 'Y'")
        return

    # ── explain ───────────────────────────────────────────────────────
    if cmd == "explain":
        rule_id = args[1] if len(args) > 1 else None
        if not rule_id:
            print("Kullanım: python -m aicontract explain <KURAL_ID>")
            print("Örnek:    python -m aicontract explain SQL003")
            return
        _explain_rule(rule_id)
        return

    # ── version ───────────────────────────────────────────────────────
    if cmd == "version":
        from . import __version__
        print(f"aicontract {__version__}")
        return

    print(f"Bilinmeyen komut: {cmd}")
    print("Yardım için: python -m aicontract --help")
    sys.exit(1)


# ── explain implementasyonu — Rashid + Hana kararı ──────────────────

RULE_DOCS = {
    "SQL003": {
        "title": "f-string / string concat ile SQL",
        "why": "SQL injection en yaygın güvenlik açığı. Kullanıcı girdisi doğrudan sorguya girince saldırgan veritabanını ele geçirebilir.",
        "bad": 'query = f"SELECT * FROM users WHERE name={user_input}"',
        "good": 'cursor.execute("SELECT * FROM users WHERE name = %s", (user_input,))',
        "refs": ["OWASP A03:2021", "CWE-89"],
    },
    "SQL002": {
        "title": "WHERE'siz DELETE / UPDATE",
        "why": "WHERE olmadan tüm tablo silinir veya güncellenir. Geri alınamaz.",
        "bad": 'db.execute("DELETE FROM orders")',
        "good": 'db.execute("DELETE FROM orders WHERE status = %s AND created_at < %s", (status, cutoff))',
        "refs": ["CWE-943"],
    },
    "SQL004": {
        "title": "Loop içinde DB sorgusu (N+1)",
        "why": "100 satır için 100 sorgu gönderilir. JOIN veya batch ile 1 sorguda çözülebilir.",
        "bad": "for user in users:\n    orders = db.query(f'SELECT * FROM orders WHERE uid={user.id}')",
        "good": "orders = db.query('SELECT * FROM orders WHERE uid = ANY(%s)', ([u.id for u in users],))",
        "refs": ["PERF-001"],
    },
    "AI002": {
        "title": "Bare except",
        "why": "Tüm hatalar yutulur — KeyboardInterrupt dahil. Debug imkansız, hata sessizce kaybolur.",
        "bad": "try:\n    risky()\nexcept:\n    pass",
        "good": "try:\n    risky()\nexcept ValueError as e:\n    logger.error('risky failed: %s', e)\n    raise",
        "refs": ["PEP-8", "Effective Python Item 65"],
    },
    "AI007": {
        "title": "Tip hint eksik",
        "why": "YZ ve IDE fonksiyonun ne alıp ne döndürdüğünü bilmez. Hatalı kullanım artar.",
        "bad": "def get_user(id):\n    return db.query(id)",
        "good": "def get_user(user_id: int) -> Optional[dict]:\n    return db.query(user_id)",
        "refs": ["PEP-484", "mypy"],
    },
    "SEC001": {
        "title": "Hardcoded secret",
        "why": "Kaynak kodda gizli bilgi git history'ye girer, sonsuza kadar kalır.",
        "bad": 'API_KEY = "sk-abc123..."',
        "good": 'API_KEY = os.environ.get("API_KEY")',
        "refs": ["CWE-798", "OWASP A02:2021"],
    },
    "AI008": {
        "title": "with olmadan open()",
        "why": "Hata durumunda dosya kapanmaz, file descriptor sızıntısı oluşur.",
        "bad": 'f = open("data.txt")\ncontent = f.read()',
        "good": 'with open("data.txt") as f:\n    content = f.read()',
        "refs": ["PEP-343"],
    },
    "ARCH001": {
        "title": "God function (40+ satır)",
        "why": "Uzun fonksiyon tek sorumluluk ilkesini ihlal eder, test edilmesi zor, YZ'nin analizi zorlaşır.",
        "bad": "# 80 satırlık login() — validasyon, DB, JWT, email hepsi içinde",
        "good": "# validate_credentials() + create_session() + send_welcome_email() ayrı fonksiyonlar",
        "refs": ["Clean Code - Robert Martin", "SRP"],
    },
    "AI003": {
        "title": "Magic number",
        "why": "86400 ne demek? 1000 ne demek? Anlamı olmayan sayı kodu okunmaz yapar.",
        "bad": "if age > 18 and retries < 3:",
        "good": "MIN_AGE = 18\nMAX_RETRIES = 3\nif age > MIN_AGE and retries < MAX_RETRIES:",
        "refs": ["Clean Code Ch.17"],
    },
}


def _explain_rule(rule_id: str):
    doc = RULE_DOCS.get(rule_id.upper())
    if not doc:
        print(f"[{rule_id}] için açıklama bulunamadı.")
        known = ", ".join(RULE_DOCS.keys())
        print(f"Bilinen kurallar: {known}")
        return

    B = "\033[1m"; D = "\033[2m"; R = "\033[0m"
    RD = "\033[91m"; GR = "\033[92m"; YL = "\033[93m"

    print(f"\n{B}[{rule_id}]{R} — {doc['title']}\n")
    print(f"{B}Neden önemli?{R}")
    print(f"  {doc['why']}\n")
    print(f"{RD}✗ Kötü:{R}")
    for line in doc["bad"].split("\n"):
        print(f"  {D}{line}{R}")
    print(f"\n{GR}✓ İyi:{R}")
    for line in doc["good"].split("\n"):
        print(f"  {line}")
    if doc.get("refs"):
        print(f"\n{D}Referanslar: {', '.join(doc['refs'])}{R}")
    print()


if __name__ == "__main__":
    main()
