# qa-copilot/perf_results.py
"""
Performance test results ingestion and dashboard queries (#20).

Stores load test results from Gatling, JMeter, and k6.
Provides trend queries for charting (p95, rps, error rate over time).
"""
from __future__ import annotations

import datetime
import json
import sqlite3
import uuid
from pathlib import Path

SCRIPT_DIR = Path(__file__).parent
_DEFAULT_DB = str(SCRIPT_DIR / "perf_results.db")


def init_db(db_path: str = _DEFAULT_DB) -> None:
    conn = sqlite3.connect(db_path)
    conn.execute("PRAGMA journal_mode=WAL")
    conn.execute("""
        CREATE TABLE IF NOT EXISTS perf_runs (
            id          TEXT PRIMARY KEY,
            tool        TEXT NOT NULL,
            scenario    TEXT NOT NULL DEFAULT '',
            metrics     TEXT NOT NULL,
            created_at  TEXT NOT NULL
        )
    """)
    conn.execute("CREATE INDEX IF NOT EXISTS idx_perf_scenario ON perf_runs(scenario, created_at DESC)")
    conn.execute("CREATE INDEX IF NOT EXISTS idx_perf_tool ON perf_runs(tool)")
    conn.commit()
    conn.close()


def ingest_result(tool: str, scenario: str, metrics: dict, db_path: str = _DEFAULT_DB) -> str:
    run_id = str(uuid.uuid4())[:8]
    now = datetime.datetime.utcnow().isoformat()
    conn = sqlite3.connect(db_path)
    conn.execute(
        "INSERT INTO perf_runs (id, tool, scenario, metrics, created_at) VALUES (?,?,?,?,?)",
        (run_id, tool, scenario, json.dumps(metrics), now),
    )
    conn.commit()
    conn.close()
    return run_id


def get_results(tool: str | None = None, scenario: str | None = None, limit: int = 50, db_path: str = _DEFAULT_DB) -> list[dict]:
    conn = sqlite3.connect(db_path)
    query = "SELECT id, tool, scenario, metrics, created_at FROM perf_runs"
    params: list = []
    conditions = []
    if tool:
        conditions.append("tool = ?")
        params.append(tool)
    if scenario:
        conditions.append("scenario = ?")
        params.append(scenario)
    if conditions:
        query += " WHERE " + " AND ".join(conditions)
    query += " ORDER BY created_at DESC LIMIT ?"
    params.append(limit)
    rows = conn.execute(query, params).fetchall()
    conn.close()
    return [
        {"id": r[0], "tool": r[1], "scenario": r[2], **json.loads(r[3]), "created_at": r[4]}
        for r in rows
    ]


def get_trend(scenario: str, metric_keys: list[str] | None = None, limit: int = 30, db_path: str = _DEFAULT_DB) -> list[dict]:
    conn = sqlite3.connect(db_path)
    rows = conn.execute(
        "SELECT id, tool, metrics, created_at FROM perf_runs WHERE scenario = ? ORDER BY created_at DESC LIMIT ?",
        (scenario, limit),
    ).fetchall()
    conn.close()
    results = []
    for r in reversed(rows):
        metrics = json.loads(r[2])
        entry = {"run_id": r[0], "tool": r[1], "created_at": r[3]}
        if metric_keys:
            for k in metric_keys:
                entry[k] = metrics.get(k)
        else:
            entry.update(metrics)
        results.append(entry)
    return results
