# retoor <retoor@molodetz.nl>

import time
import uuid

import requests

from tests.conftest import BASE_URL
from devplacepy.database import get_table, refresh_snapshot
from devplacepy.services.jobs.isslop import store
from devplacepy.utils import generate_uid

_counter_isslop = [0]


def _json_headers():
    return {"Accept": "application/json"}


def _unique(prefix="sl"):
    _counter_isslop[0] += 1
    return f"{prefix}{int(time.time() * 1000)}{_counter_isslop[0]}"


def _clear_isslop_data():
    refresh_snapshot()
    jobs = get_table("jobs")
    for row in list(jobs.find(kind="isslop")):
        jobs.delete(uid=row["uid"])
    analyses = get_table("isslop_analyses")
    for row in list(analyses.find()):
        analyses.delete(uid=row["uid"])


def test_isslop_page_renders(app_server):
    r = requests.get(f"{BASE_URL}/tools/isslop")
    assert r.status_code == 200
    assert "AI Usage Analyzer" in r.text
    assert "<dp-isslop>" in r.text
    assert "devii_guest" in r.headers.get("set-cookie", "")


def test_run_enqueues_and_creates_analysis(app_server):
    session = requests.Session()
    try:
        r = session.post(
            f"{BASE_URL}/tools/isslop/run",
            headers=_json_headers(),
            data={"url": "https://github.com/owner/repository"},
        )
        assert r.status_code == 200, r.text
        body = r.json()
        uid = body["uid"]
        assert body["status_url"] == f"/tools/isslop/{uid}"
        assert body["events_url"] == f"/tools/isslop/{uid}/events"
        assert body["report_url"] == f"/tools/isslop/{uid}/report"
        assert body["topic"] == f"public.isslop.{uid}"

        refresh_snapshot()
        job = get_table("jobs").find_one(uid=uid)
        assert job is not None
        assert job["kind"] == "isslop"
        assert job["status"] == "pending"

        analysis = get_table("isslop_analyses").find_one(uid=uid)
        assert analysis is not None
        assert analysis["status"] == "pending"
        assert analysis["owner_kind"] == "guest"
        assert analysis["source_url"] == "https://github.com/owner/repository"
        assert analysis["deleted_at"] is None

        status = session.get(f"{BASE_URL}/tools/isslop/{uid}", headers=_json_headers())
        assert status.status_code == 200
        assert status.json()["status"] == "pending"
        assert status.json()["source_url"] == "https://github.com/owner/repository"

        events = session.get(f"{BASE_URL}/tools/isslop/{uid}/events", headers=_json_headers())
        assert events.status_code == 200
        assert events.json()["events"] == []

        badge = session.get(f"{BASE_URL}/tools/isslop/{uid}/badge.svg")
        assert badge.status_code == 200
        assert badge.headers["content-type"].startswith("image/svg+xml")
        assert "analyzing" in badge.text

        listing = session.get(f"{BASE_URL}/tools/isslop/list", headers=_json_headers())
        assert listing.status_code == 200
        uids = [row["uid"] for row in listing.json()["analyses"]]
        assert uid in uids
    finally:
        _clear_isslop_data()


def test_second_active_run_is_denied(app_server):
    session = requests.Session()
    try:
        first = session.post(
            f"{BASE_URL}/tools/isslop/run",
            headers=_json_headers(),
            data={"url": "https://github.com/owner/repository"},
        )
        assert first.status_code == 200
        second = session.post(
            f"{BASE_URL}/tools/isslop/run",
            headers=_json_headers(),
            data={"url": "https://github.com/owner/other"},
        )
        assert second.status_code == 429
        assert second.json()["error"]["uid"] == first.json()["uid"]
    finally:
        _clear_isslop_data()


def test_invalid_url_is_rejected(app_server):
    session = requests.Session()
    try:
        r = session.post(
            f"{BASE_URL}/tools/isslop/run",
            headers=_json_headers(),
            data={"url": "ftp://example.com/archive"},
            allow_redirects=False,
        )
        assert r.status_code != 200
        refresh_snapshot()
        assert get_table("jobs").find_one(kind="isslop") is None
    finally:
        _clear_isslop_data()


def test_status_unknown_uid_404(app_server):
    r = requests.get(f"{BASE_URL}/tools/isslop/does-not-exist", headers=_json_headers())
    assert r.status_code == 404


def test_report_json_while_pending(app_server):
    session = requests.Session()
    try:
        run = session.post(
            f"{BASE_URL}/tools/isslop/run",
            headers=_json_headers(),
            data={"url": "https://github.com/owner/repository"},
        )
        uid = run.json()["uid"]
        report = session.get(f"{BASE_URL}/tools/isslop/{uid}/report", headers=_json_headers())
        assert report.status_code == 200
        body = report.json()
        assert body["status"] == "pending"
        assert body["markdown"] == ""
        assert body["badge"]["badge_url"].endswith(f"/tools/isslop/{uid}/badge.svg")

        html = session.get(f"{BASE_URL}/tools/isslop/{uid}/report")
        assert html.status_code == 200
        assert "dp-isslop-run" in html.text
        assert 'class="breadcrumb"' in html.text
        assert "sidebar-card" in html.text

        download = session.get(f"{BASE_URL}/tools/isslop/{uid}/report.md")
        assert download.status_code == 404
    finally:
        _clear_isslop_data()


def test_guest_history_claimed_on_signup(app_server):
    session = requests.Session()
    try:
        run = session.post(
            f"{BASE_URL}/tools/isslop/run",
            headers=_json_headers(),
            data={"url": "https://github.com/owner/repository"},
        )
        uid = run.json()["uid"]
        name = _unique("slopuser")
        session.post(
            f"{BASE_URL}/auth/signup",
            data={
                "username": name,
                "email": f"{name}@t.dev",
                "password": "secret123",
                "confirm_password": "secret123",
                "birth_date": "1990-01-01",
                "accept_terms": "1",
            },
            allow_redirects=True,
        )
        listing = session.get(f"{BASE_URL}/tools/isslop/list", headers=_json_headers())
        assert listing.status_code == 200
        rows = [row for row in listing.json()["analyses"] if row["uid"] == uid]
        assert len(rows) == 1

        refresh_snapshot()
        analysis = get_table("isslop_analyses").find_one(uid=uid)
        user = get_table("users").find_one(username=name)
        assert analysis["owner_kind"] == "user"
        assert analysis["owner_id"] == user["uid"]
        assert get_table("isslop_analyses").count(uid=uid) == 1
    finally:
        _clear_isslop_data()


def test_source_route_serves_the_annotated_file(app_server):
    uid = generate_uid()
    store.create_analysis(uid, "https://github.com/owner/repository", "guest", "src-owner")
    source_name = "s" + uuid.uuid4().hex[:16] + ".txt"
    store.insert_file_result(
        uid,
        {
            "path": "app.py",
            "language": "python",
            "lines": 1,
            "origin_score": 0.1,
            "quality_deficit_score": 0.1,
            "category": "human-authored",
            "signals": "[]",
            "source": source_name,
        },
    )
    media_dir = store.media_dir_for(uid)
    media_dir.mkdir(parents=True, exist_ok=True)
    (media_dir / source_name).write_text("print('hello')\n", encoding="utf-8")
    try:
        r = requests.get(
            f"{BASE_URL}/tools/isslop/{uid}/source",
            params={"path": "app.py"},
            headers=_json_headers(),
        )
        assert r.status_code == 200, r.text
        body = r.json()
        assert "print" in body["source"]
        assert body["path"] == "app.py"
    finally:
        store.purge_analysis(uid)


def test_source_route_rejects_an_unsafe_source_token(app_server):
    uid = generate_uid()
    store.create_analysis(uid, "https://github.com/owner/repository", "guest", "src-traversal-owner")
    store.insert_file_result(
        uid,
        {
            "path": "app.py",
            "language": "python",
            "lines": 1,
            "origin_score": 0.0,
            "quality_deficit_score": 0.0,
            "category": "human-authored",
            "signals": "[]",
            "source": "../../../../etc/passwd",
        },
    )
    try:
        r = requests.get(
            f"{BASE_URL}/tools/isslop/{uid}/source",
            params={"path": "app.py"},
            headers=_json_headers(),
        )
        assert r.status_code == 404
    finally:
        store.purge_analysis(uid)


def test_media_route_serves_a_thumbnail(app_server):
    uid = generate_uid()
    store.create_analysis(uid, "https://github.com/owner/repository", "guest", "media-owner")
    name = uuid.uuid4().hex[:16] + ".webp"
    store.insert_image_result(
        uid,
        {
            "path": "assets/hero.png",
            "ai_probability": 0.2,
            "grade": "n/a",
            "verdict": "uncertain",
            "image_kind": "image",
            "tells": "[]",
            "description": "",
            "thumb": name,
        },
    )
    media_dir = store.media_dir_for(uid)
    media_dir.mkdir(parents=True, exist_ok=True)
    (media_dir / name).write_bytes(b"not-a-real-webp-but-bytes")
    try:
        r = requests.get(f"{BASE_URL}/tools/isslop/{uid}/media/{name}")
        assert r.status_code == 200, r.text
        assert r.headers["content-type"].startswith("image/webp")
        assert r.content == b"not-a-real-webp-but-bytes"
    finally:
        store.purge_analysis(uid)


def test_media_route_rejects_a_name_outside_the_hex_pattern(app_server):
    uid = generate_uid()
    store.create_analysis(uid, "https://github.com/owner/repository", "guest", "media-traversal-owner")
    try:
        r = requests.get(f"{BASE_URL}/tools/isslop/{uid}/media/..%2fetc%2fpasswd")
        assert r.status_code == 404, r.text
    finally:
        store.purge_analysis(uid)
