from __future__ import annotations

import hashlib
import json
import math
import random
import secrets
import sqlite3
from datetime import datetime, timedelta, timezone
from collections import defaultdict

from .db import Database
from .auth import hash_password, new_token, token_hash, verify_password


class NotFound(Exception): pass
class Conflict(Exception): pass
class Invalid(Exception): pass


class Service:
    def __init__(self, db: Database, rng: random.Random | None = None):
        self.db, self.rng = db, rng or random.SystemRandom()

    def create_release(self, data, project_id=None, application=None):
        try:
            with self.db.connect() as con:
                fields = ("application", "version", "project_id", "repository_url", "source_commit", "spec_path",
                          "artifact_url", "artifact_name", "artifact_sha256", "evidence_sha256",
                          "signing_public_key", "signature", "channel")
                values = tuple(
                    (application or data.application) if field == "application" else project_id if field == "project_id" else getattr(data, field)
                    for field in fields
                )
                cur = con.execute(
                    f"INSERT INTO releases({','.join(fields)}) VALUES ({','.join('?' for _ in fields)})",
                    values,
                )
                rid = cur.lastrowid
                seen = set()
                for spec in data.spec_functions:
                    if spec.name in seen: raise Invalid(f"duplicate spec function: {spec.name}")
                    seen.add(spec.name)
                    sid = con.execute("INSERT INTO spec_functions(release_id,name) VALUES (?,?)", (rid, spec.name)).lastrowid
                    for impl in spec.implementations:
                        con.execute("INSERT INTO implementations(release_id,id,spec_function_id,name,provenance) VALUES (?,?,?,?,?)",
                                    (rid, impl.id, sid, impl.name, json.dumps(impl.provenance, sort_keys=True)))
            return self.release(rid)
        except sqlite3.IntegrityError as e:
            raise Conflict(str(e)) from e

    def create_user(self, data):
        try:
            with self.db.connect() as con:
                user_id = con.execute(
                    "INSERT INTO users(username,email,password_hash) VALUES (?,?,?)",
                    (data.username.lower(), data.email.lower(),
                     hash_password(data.password)),
                ).lastrowid
            return self.user(user_id)
        except sqlite3.IntegrityError as error:
            raise Conflict("username or email is already registered") from error

    def authenticate(self, username, password):
        with self.db.connect() as con:
            row = con.execute("SELECT * FROM users WHERE username=? COLLATE NOCASE", (username,)).fetchone()
        if not row or not verify_password(password, row["password_hash"]):
            raise Invalid("invalid username or password")
        return self._public_user(row)

    def user(self, user_id):
        with self.db.connect() as con:
            row = con.execute("SELECT * FROM users WHERE id=?", (user_id,)).fetchone()
        if not row: raise NotFound("user not found")
        return self._public_user(row)

    def user_by_username(self, username):
        with self.db.connect() as con:
            row = con.execute("SELECT * FROM users WHERE username=? COLLATE NOCASE", (username,)).fetchone()
        if not row: raise NotFound("user not found")
        return self._public_user(row)

    @staticmethod
    def _public_user(row):
        return {key: row[key] for key in ("id", "username", "created_at")}

    def create_session(self, user_id):
        token = new_token("ps_")
        expires = (datetime.now(timezone.utc) + timedelta(days=30)).strftime("%Y-%m-%d %H:%M:%S")
        with self.db.connect() as con:
            con.execute("INSERT INTO sessions(token_hash,user_id,expires_at) VALUES (?,?,?)",
                        (token_hash(token), user_id, expires))
        return token

    def session_user(self, token):
        if not token: return None
        with self.db.connect() as con:
            row = con.execute("""SELECT u.* FROM sessions s JOIN users u ON u.id=s.user_id
              WHERE s.token_hash=? AND s.expires_at>CURRENT_TIMESTAMP""", (token_hash(token),)).fetchone()
        return self._public_user(row) if row else None

    def delete_session(self, token):
        if token:
            with self.db.connect() as con:
                con.execute("DELETE FROM sessions WHERE token_hash=?", (token_hash(token),))

    def create_api_token(self, user_id, label):
        token = new_token("pf_")
        with self.db.connect() as con:
            con.execute("INSERT INTO api_tokens(token_hash,user_id,label) VALUES (?,?,?)",
                        (token_hash(token), user_id, label))
        return token

    def api_token_user(self, token):
        if not token: return None
        digest = token_hash(token)
        with self.db.connect() as con:
            row = con.execute("""SELECT u.* FROM api_tokens t JOIN users u ON u.id=t.user_id
              WHERE t.token_hash=?""", (digest,)).fetchone()
            if row: con.execute("UPDATE api_tokens SET last_used_at=CURRENT_TIMESTAMP WHERE token_hash=?", (digest,))
        return self._public_user(row) if row else None

    def create_project(self, user_id, data):
        try:
            with self.db.connect() as con:
                project_id = con.execute("""INSERT INTO projects(
                  owner_user_id,slug,name,description,repository_url,spec_path
                ) VALUES (?,?,?,?,?,?)""", (user_id,data.slug,data.name,data.description,
                                              data.repository_url,data.spec_path)).lastrowid
            return self.project_by_id(project_id)
        except sqlite3.IntegrityError as error:
            raise Conflict("you already have a project with that slug") from error

    def project_by_id(self, project_id):
        with self.db.connect() as con:
            row = con.execute("""SELECT p.*,u.username owner
              FROM projects p JOIN users u ON u.id=p.owner_user_id WHERE p.id=?""", (project_id,)).fetchone()
        if not row: raise NotFound("project not found")
        return self._project(row)

    def update_project(self, user_id, owner, slug, data):
        project = self.project(owner, slug)
        if project["owner"] != owner.lower() or self.user(user_id)["username"] != project["owner"]:
            raise Invalid("project owner access required")
        with self.db.connect() as con:
            con.execute("""UPDATE projects SET name=?,description=?,repository_url=?,spec_path=?,
              updated_at=CURRENT_TIMESTAMP WHERE id=?""",
                        (data.name, data.description, data.repository_url, data.spec_path, project["id"]))
        return self.project(owner, slug)

    def project(self, owner, slug):
        with self.db.connect() as con:
            row = con.execute("""SELECT p.*,u.username owner
              FROM projects p JOIN users u ON u.id=p.owner_user_id
              WHERE u.username=? COLLATE NOCASE AND p.slug=? COLLATE NOCASE""", (owner,slug)).fetchone()
            if not row: raise NotFound("project not found")
            releases = [dict(item) for item in con.execute("""SELECT id,version,channel,artifact_url,
              artifact_name,source_commit,created_at FROM releases WHERE project_id=? ORDER BY id DESC""", (row["id"],))]
            counts = con.execute("""SELECT count(DISTINCT sf.id),count(i.pk) FROM releases r
              LEFT JOIN spec_functions sf ON sf.release_id=r.id LEFT JOIN implementations i ON i.release_id=r.id
              WHERE r.project_id=?""", (row["id"],)).fetchone()
        return {**self._project(row), "releases":releases, "spec_functions":counts[0], "implementations":counts[1]}

    def list_user_projects(self, user_id):
        with self.db.connect() as con:
            rows = con.execute("""SELECT p.*,u.username owner
              FROM projects p JOIN users u ON u.id=p.owner_user_id WHERE p.owner_user_id=?
              ORDER BY p.updated_at DESC,p.id DESC""", (user_id,)).fetchall()
        return [self._project(row) for row in rows]

    def public_user_profile(self, username):
        with self.db.connect() as con:
            user = con.execute(
                "SELECT id,username,created_at FROM users WHERE username=? COLLATE NOCASE",
                (username,),
            ).fetchone()
            if not user:
                raise NotFound("user not found")
            rows = con.execute("""SELECT p.*,u.username owner
              FROM projects p JOIN users u ON u.id=p.owner_user_id
              WHERE p.owner_user_id=? AND p.visibility='public'
              ORDER BY p.updated_at DESC,p.id DESC""", (user["id"],)).fetchall()
        return {**self._public_user(user), "projects": [self._project(row) for row in rows]}

    def list_public_projects(self, limit=24):
        with self.db.connect() as con:
            rows = con.execute("""SELECT p.*,u.username owner
              FROM projects p JOIN users u ON u.id=p.owner_user_id WHERE p.visibility='public'
              ORDER BY p.updated_at DESC,p.id DESC LIMIT ?""", (limit,)).fetchall()
        return [self._project(row) for row in rows]

    @staticmethod
    def _project(row):
        return {key:row[key] for key in ("id","owner","slug","name","description",
                                         "repository_url","spec_path","visibility","created_at","updated_at")}

    def publish_project_release(self, user_id, owner, slug, data):
        project = self.project(owner, slug)
        if project["owner"] != owner.lower() or self.user(user_id)["username"] != project["owner"]:
            raise Invalid("project owner access required")
        if not data.repository_url and project["repository_url"]:
            data.repository_url = project["repository_url"]
        if not data.spec_path and project["spec_path"]:
            data.spec_path = project["spec_path"]
        return self.create_release(data, project["id"], f"{project['owner']}/{project['slug']}")

    def release_project_owner(self, release_id):
        with self.db.connect() as con:
            row = con.execute("""SELECT u.id user_id,u.username FROM releases r JOIN projects p ON p.id=r.project_id
              JOIN users u ON u.id=p.owner_user_id WHERE r.id=?""", (release_id,)).fetchone()
        return dict(row) if row else None

    def release(self, rid):
        with self.db.connect() as con:
            rel = con.execute("SELECT * FROM releases WHERE id=?", (rid,)).fetchone()
            if not rel: raise NotFound("release not found")
            rows = con.execute("""SELECT sf.name spec_function,i.id,i.name,i.status,i.status_reason,i.provenance
              FROM spec_functions sf JOIN implementations i ON i.spec_function_id=sf.id
              WHERE sf.release_id=? ORDER BY sf.name,i.id""", (rid,)).fetchall()
        specs = defaultdict(list)
        for r in rows:
            specs[r["spec_function"]].append({"id": r["id"], "name": r["name"], "status": r["status"],
                                              "status_reason": r["status_reason"], "provenance": json.loads(r["provenance"])})
        return {**dict(rel), "spec_functions": [{"name": k, "implementations": v} for k,v in specs.items()]}

    def list_releases(self):
        with self.db.connect() as con:
            ids = [r[0] for r in con.execute("SELECT id FROM releases ORDER BY id DESC")]
        return [self.release(i) for i in ids]

    def catalog(self, application=None, version=None):
        clauses, params = ["artifact_url IS NOT NULL"], []
        if application is not None:
            clauses.append("application=?"); params.append(application)
        if version is not None:
            clauses.append("version=?"); params.append(version)
        with self.db.connect() as con:
            rows = con.execute(
                "SELECT id FROM releases WHERE " + " AND ".join(clauses) + " ORDER BY id DESC",
                params,
            ).fetchall()
        if application is not None:
            if not rows: raise NotFound("published application release not found")
            return self.release(rows[0]["id"])
        return [self.release(row["id"]) for row in rows]

    def project_catalog(self, owner, slug, version=None):
        project = self.project(owner, slug)
        clauses, params = ["project_id=?", "artifact_url IS NOT NULL"], [project["id"]]
        if version is not None:
            clauses.append("version=?"); params.append(version)
        with self.db.connect() as con:
            row = con.execute("SELECT id FROM releases WHERE " + " AND ".join(clauses) +
                              " ORDER BY id DESC LIMIT 1", params).fetchone()
        if not row: raise NotFound("published project release not found")
        return self.release(row["id"])

    def _eligible(self, con, rid):
        rows = con.execute("""SELECT sf.id spec_id,sf.name spec_function,i.pk implementation_pk,i.id implementation_id
          FROM spec_functions sf JOIN implementations i ON i.spec_function_id=sf.id
          WHERE sf.release_id=? AND i.status='active' ORDER BY sf.name,i.id""", (rid,)).fetchall()
        grouped = defaultdict(list)
        for r in rows:
            grouped[(r["spec_id"],r["spec_function"])].append((r["implementation_pk"],r["implementation_id"]))
        total = con.execute("SELECT count(*) FROM spec_functions WHERE release_id=?", (rid,)).fetchone()[0]
        if len(grouped) != total: raise Conflict("release has a spec function with no active implementation")
        return grouped

    def _choose(self, con, rid, strategy):
        grouped = self._eligible(con, rid)
        chosen = {}
        for (sid, name), implementations in grouped.items():
            if strategy == "homogeneous": pick = implementations[0]
            elif strategy == "random": pick = self.rng.choice(implementations)
            else:
                pks = [item[0] for item in implementations]
                placeholders = ",".join("?" for _ in pks)
                usage = dict(con.execute(f"""SELECT ci.implementation_pk,count(*) n FROM composition_items ci
                  JOIN compositions c ON c.id=ci.composition_id
                  WHERE c.replaced_at IS NULL AND ci.implementation_pk IN ({placeholders}) GROUP BY ci.implementation_pk""", pks).fetchall())
                low = min(usage.get(item[0], 0) for item in implementations)
                pick = self.rng.choice([item for item in implementations if usage.get(item[0],0)==low])
            chosen[sid] = (name, pick[0], pick[1])
        return chosen

    def _compose(self, con, client_id, rid, strategy, reason):
        chosen = self._choose(con, rid, strategy)
        old = con.execute("SELECT id,generation FROM compositions WHERE client_id=? AND replaced_at IS NULL", (client_id,)).fetchone()
        generation = 1 if not old else old["generation"] + 1
        if old: con.execute("UPDATE compositions SET replaced_at=CURRENT_TIMESTAMP WHERE id=?", (old["id"],))
        cid = con.execute("INSERT INTO compositions(client_id,generation,reason) VALUES (?,?,?)", (client_id,generation,reason)).lastrowid
        for sid, (_, impl_pk, _) in chosen.items():
            con.execute("INSERT INTO composition_items VALUES (?,?,?)", (cid,sid,impl_pk))
        return cid

    def register_client(self, data):
        install_hash = (hashlib.sha256(f"{data.release_id}\0{data.installation_id}".encode()).hexdigest()
                        if data.installation_id else None)
        legacy_hash = hashlib.sha256(data.installation_id.encode()).hexdigest() if data.installation_id else None
        with self.db.connect() as con:
            if not con.execute("SELECT 1 FROM releases WHERE id=?", (data.release_id,)).fetchone(): raise NotFound("release not found")
            existing = con.execute("SELECT id,installation_hash FROM clients WHERE release_id=? AND installation_hash IN (?,?)",
                                   (data.release_id,install_hash,legacy_hash)).fetchone() if install_hash else None
            if existing:
                client_id = existing[0]
                con.execute("UPDATE clients SET installation_hash=?,last_seen_at=CURRENT_TIMESTAMP WHERE id=?", (install_hash,client_id))
            else:
                client_id = "pc_" + secrets.token_urlsafe(18)
                con.execute("INSERT INTO clients(id,installation_hash,release_id,strategy) VALUES (?,?,?,?)",
                            (client_id,install_hash,data.release_id,data.strategy))
                self._compose(con,client_id,data.release_id,data.strategy,"registration")
        return self.composition(client_id)

    def composition(self, client_id):
        with self.db.connect() as con:
            client = con.execute("SELECT * FROM clients WHERE id=?", (client_id,)).fetchone()
            if not client: raise NotFound("client not found")
            comp = con.execute("SELECT * FROM compositions WHERE client_id=? AND replaced_at IS NULL", (client_id,)).fetchone()
            rows = con.execute("""SELECT sf.name,i.id,i.status FROM composition_items ci
              JOIN spec_functions sf ON sf.id=ci.spec_function_id JOIN implementations i ON i.pk=ci.implementation_pk
              WHERE ci.composition_id=? ORDER BY sf.name""", (comp["id"],)).fetchall()
        reason=comp["reason"].split(":",1)[0]
        return {"client_id":client_id,"release_id":str(client["release_id"]),"revision":comp["generation"],
                "reason":reason,"implementations":{r["name"]:r["id"] for r in rows}}

    def execution(self, data):
        with self.db.connect() as con:
            comp = con.execute("SELECT id FROM compositions WHERE client_id=? AND generation=?", (data.client_id,data.composition_revision)).fetchone()
            if not comp: raise NotFound("client not found")
            self._validate_calls(con,comp["id"],data.calls)
            eid = con.execute("INSERT INTO executions(client_id,composition_id,operation,success,duration_ms,error_kind) VALUES (?,?,?,?,?,?)",
                              (data.client_id,comp["id"],data.operation,data.success,data.duration_ms,data.error_kind)).lastrowid
            for n,c in enumerate(data.calls):
                con.execute("INSERT INTO calls(execution_id,ordinal,spec_function,implementation_id,outcome,duration_ms) VALUES (?,?,?,?,?,?)",
                            (eid,n,c.spec_function,c.implementation_id,c.outcome,c.duration_ms))
        return {"execution_id":eid}

    def telemetry(self, data):
        with self.db.connect() as con:
            comp = con.execute("SELECT id FROM compositions WHERE client_id=? AND generation=?", (data.client_id,data.composition_revision)).fetchone()
            if not comp: raise NotFound("client not found")
            client=con.execute("SELECT release_id FROM clients WHERE id=?",(data.client_id,)).fetchone()
            if str(client["release_id"]) != data.release_id:
                raise Invalid("telemetry release does not belong to client")
            attributed=con.execute("""SELECT 1 FROM composition_items ci JOIN spec_functions sf ON sf.id=ci.spec_function_id
              JOIN implementations i ON i.pk=ci.implementation_pk
              WHERE ci.composition_id=? AND sf.name=? AND i.id=?""",
              (comp["id"],data.spec_function,data.implementation_id)).fetchone()
            if not attributed:
                raise Invalid("implementation was not active for this composition")
            self._validate_calls(con,comp["id"],data.recent_calls)
            if data.execution_id and not con.execute("SELECT 1 FROM executions WHERE id=? AND client_id=? AND composition_id=?", (data.execution_id,data.client_id,comp["id"])).fetchone():
                raise Invalid("execution does not belong to client and composition")
            tid = con.execute("""INSERT INTO telemetry_events(client_id,composition_id,execution_id,event_type,spec_function,implementation_id,message,recent_calls)
              VALUES (?,?,?,?,?,?,?,?)""", (data.client_id,comp["id"],data.execution_id,data.event_type,data.spec_function,
                data.implementation_id,data.message_code,json.dumps([x.model_dump() for x in data.recent_calls]))).lastrowid
        return {"telemetry_id":tid}

    def set_status(self, impl_id, data, release_id=None):
        with self.db.connect() as con:
            rows = con.execute("SELECT pk,status,spec_function_id,release_id FROM implementations WHERE id=?" +
                               (" AND release_id=?" if release_id is not None else ""),
                               ((impl_id,release_id) if release_id is not None else (impl_id,))).fetchall()
            if not rows: raise NotFound("implementation not found")
            if len(rows) > 1:
                raise Conflict("implementation ID exists in multiple releases; provide release_id")
            row = rows[0]
            if row["status"] == data.status:
                return {"implementation_id":impl_id,"release_id":row["release_id"],
                        "status":data.status,"affected_clients":0}
            if data.status != "active":
                active = con.execute("SELECT count(*) FROM implementations WHERE spec_function_id=? AND status='active' AND pk<>?", (row["spec_function_id"],row["pk"])).fetchone()[0]
                if not active: raise Conflict("cannot remove the final active implementation")
            affected = [r[0] for r in con.execute("""SELECT DISTINCT c.client_id FROM compositions c JOIN composition_items ci ON ci.composition_id=c.id
               WHERE c.replaced_at IS NULL AND ci.implementation_pk=?""", (row["pk"],))]
            con.execute("UPDATE implementations SET status=?,status_reason=?,status_changed_at=CURRENT_TIMESTAMP WHERE pk=?",
                        (data.status,data.reason,row["pk"]))
            recomposed = 0
            if data.status != "active":
                for client_id in affected:
                    cl = con.execute("SELECT release_id,strategy FROM clients WHERE id=?", (client_id,)).fetchone()
                    self._compose(con,client_id,cl["release_id"],cl["strategy"],"quarantine" if data.status=="quarantined" else "manual")
                    recomposed += 1
            cutoff=con.execute("SELECT coalesce(max(id),0) FROM executions").fetchone()[0]
            con.execute("INSERT INTO status_changes(implementation_pk,old_status,new_status,reason,affected_clients,execution_cutoff) VALUES (?,?,?,?,?,?)",
                        (row["pk"],row["status"],data.status,data.reason,recomposed,cutoff))
        return {"implementation_id":impl_id,"release_id":row["release_id"],"status":data.status,"affected_clients":recomposed}

    def _validate_calls(self, con, composition_id, calls):
        assigned = {r["spec_function"]:r["implementation_id"] for r in con.execute("""SELECT sf.name spec_function,i.id implementation_id
          FROM composition_items ci JOIN spec_functions sf ON sf.id=ci.spec_function_id
          JOIN implementations i ON i.pk=ci.implementation_pk
          WHERE ci.composition_id=?""",(composition_id,))}
        for call in calls:
            if assigned.get(call.spec_function) != call.implementation_id:
                raise Invalid("call implementation was not active for this composition")

    def implementation_stats(self, rid=None):
        where, params = ("WHERE sf.release_id=?", (rid,)) if rid else ("", ())
        with self.db.connect() as con:
            impls = con.execute(f"""SELECT i.pk internal_pk,i.id,i.release_id,i.name,i.status,i.provenance,sf.name spec_function FROM implementations i
              JOIN spec_functions sf ON sf.id=i.spec_function_id {where} ORDER BY sf.name,i.id""", params).fetchall()
            executions = con.execute("""SELECT e.id,e.success,e.composition_id,c.release_id FROM executions e
              JOIN clients c ON c.id=e.client_id""" + (" WHERE c.release_id=?" if rid else ""), params).fetchall()
            exposure = defaultdict(set)
            for r in con.execute("SELECT composition_id,implementation_pk FROM composition_items"):
                exposure[r["composition_id"]].add(r["implementation_pk"])
        out=[]
        for impl in impls:
            same_release=[e for e in executions if e["release_id"] == impl["release_id"]]
            carrier=[e for e in same_release if impl["internal_pk"] in exposure[e["composition_id"]]]
            other=[e for e in same_release if impl["internal_pk"] not in exposure[e["composition_id"]]]
            fail=sum(not e["success"] for e in carrier); ofail=sum(not e["success"] for e in other)
            rate=fail/len(carrier) if carrier else 0.0; baseline=ofail/len(other) if other else 0.0
            rr=(rate/baseline if baseline else (math.inf if rate else 1.0))
            clients=len({e["composition_id"] for e in carrier})
            try: provenance=json.loads(impl["provenance"])
            except (TypeError, json.JSONDecodeError): provenance={}
            public = {key: value for key,value in dict(impl).items() if key not in {"internal_pk", "provenance"}}
            out.append({**public,"clients_observed":clients,"executions":len(carrier),"failures":fail,
                        "experimental":bool(provenance.get("experimental", False)),
                        "source_url":provenance.get("source_url"),
                        "failure_rate":round(rate,6),"alternative_failure_rate":round(baseline,6),
                        "relative_risk":rr if math.isfinite(rr) else None,"infinite_relative_risk":not math.isfinite(rr)})
        return out

    def pairwise_stats(self, rid=None, min_executions=3):
        stats=self.implementation_stats(rid)
        with self.db.connect() as con:
            impl_rows=con.execute("""SELECT i.pk,i.id,i.release_id FROM implementations i JOIN spec_functions sf ON sf.id=i.spec_function_id""" +
                (" WHERE sf.release_id=?" if rid else ""), (rid,) if rid else ()).fetchall()
            wanted={row["pk"] for row in impl_rows}
            public={row["pk"]:(row["id"],row["release_id"]) for row in impl_rows}
            execs=con.execute("""SELECT e.success,e.composition_id FROM executions e JOIN clients c ON c.id=e.client_id""" +
                (" WHERE c.release_id=?" if rid else ""), (rid,) if rid else ()).fetchall()
            exposures=defaultdict(set)
            for r in con.execute("SELECT composition_id,implementation_pk FROM composition_items"):
                if r["implementation_pk"] in wanted: exposures[r["composition_id"]].add(r["implementation_pk"])
        marginal={(item["release_id"],item["id"]):item["failure_rate"] for item in stats}
        pairs=defaultdict(lambda:[0,0])
        for e in execs:
            ids=sorted(exposures[e["composition_id"]])
            for a in range(len(ids)):
                for b in range(a+1,len(ids)):
                    pairs[(ids[a],ids[b])][0]+=1; pairs[(ids[a],ids[b])][1]+=not e["success"]
        result=[]
        for (a,b),(n,f) in pairs.items():
            if n < min_executions: continue
            a_id,a_release=public[a]; b_id,b_release=public[b]
            singles=max(marginal[(a_release,a_id)],marginal[(b_release,b_id)])
            rate=f/n
            result.append({"implementation_a":a_id,"implementation_a_release_id":a_release,
                           "implementation_b":b_id,"implementation_b_release_id":b_release,"executions":n,"failures":f,
                           "failure_rate":round(rate,6),"interaction_lift":round(rate-singles,6)})
        return sorted(result,key=lambda x:(x["interaction_lift"],x["executions"]),reverse=True)

    def dashboard(self, rid=None):
        if rid is None:
            with self.db.connect() as con:
                latest=con.execute("SELECT id FROM releases ORDER BY id DESC LIMIT 1").fetchone()
            rid=latest["id"] if latest else None
        with self.db.connect() as con:
            rel_where, p = ("WHERE release_id=?",(rid,)) if rid else ("",())
            clients=con.execute(f"SELECT count(*) FROM clients {rel_where}",p).fetchone()[0]
            specs=con.execute("SELECT count(*) FROM spec_functions" + (" WHERE release_id=?" if rid else ""),p).fetchone()[0]
            counts=[r[0] for r in con.execute("SELECT count(*) FROM implementations i JOIN spec_functions sf ON sf.id=i.spec_function_id" + (" WHERE sf.release_id=?" if rid else "") + " GROUP BY sf.id",p)]
            active_count_where = " WHERE i.status='active'" + (" AND sf.release_id=?" if rid else "")
            active_counts=[r[0] for r in con.execute("SELECT count(*) FROM implementations i JOIN spec_functions sf ON sf.id=i.spec_function_id" + active_count_where + " GROUP BY sf.id",p)]
            theoretical=math.prod(active_counts) if len(active_counts) == specs else 0
            events=con.execute("""SELECT count(*) FROM telemetry_events te JOIN clients c ON c.id=te.client_id""" +
                (" WHERE c.release_id=?" if rid else ""),p).fetchone()[0]
            executions=con.execute("""SELECT count(*),coalesce(sum(1-e.success),0) FROM executions e
              JOIN clients c ON c.id=e.client_id""" + (" WHERE c.release_id=?" if rid else ""),p).fetchone()
            latest_execution=con.execute("""SELECT max(e.created_at) FROM executions e
              JOIN clients c ON c.id=e.client_id""" + (" WHERE c.release_id=?" if rid else ""),p).fetchone()[0]
            latest_execution_at=(latest_execution.replace(" ", "T") + "Z") if latest_execution else None
            quarantined=[dict(r) for r in con.execute("""SELECT i.id,i.release_id,i.name,i.status_reason FROM implementations i
              JOIN spec_functions sf ON sf.id=i.spec_function_id WHERE i.status='quarantined'""" +
              (" AND sf.release_id=?" if rid else ""),p)]
            changes=[dict(r) for r in con.execute("""SELECT sc.* FROM status_changes sc
              JOIN implementations i ON i.pk=sc.implementation_pk JOIN spec_functions sf ON sf.id=i.spec_function_id""" +
              (" WHERE sf.release_id=?" if rid else "") + " ORDER BY sc.id DESC LIMIT 50",p)]
            for change in changes:
                impl=con.execute("SELECT id,release_id FROM implementations WHERE pk=?",(change.pop("implementation_pk"),)).fetchone()
                change["implementation_id"],change["release_id"]=impl["id"],impl["release_id"]
            distributions=[dict(r) for r in con.execute("""SELECT sf.name spec_function,i.id implementation_id,i.release_id,count(*) clients
              FROM compositions c JOIN composition_items ci ON ci.composition_id=c.id JOIN implementations i ON i.pk=ci.implementation_pk
              JOIN spec_functions sf ON sf.id=i.spec_function_id JOIN clients cl ON cl.id=c.client_id
              WHERE c.replaced_at IS NULL""" + (" AND cl.release_id=?" if rid else "") +
              " GROUP BY sf.name,i.id,i.release_id ORDER BY sf.name,i.id",p)]
            vectors=defaultdict(list)
            for row in con.execute("""SELECT c.id composition_id,ci.spec_function_id,ci.implementation_pk
              FROM compositions c JOIN composition_items ci ON ci.composition_id=c.id
              JOIN clients cl ON cl.id=c.client_id WHERE c.replaced_at IS NULL""" +
              (" AND cl.release_id=?" if rid else "") + " ORDER BY c.id,ci.spec_function_id",p):
                vectors[row["composition_id"]].append(row["implementation_pk"])
            observed_compositions=len({tuple(vector) for vector in vectors.values()})
            history=[dict(r) for r in con.execute("""SELECT c.generation,c.reason,count(*) count FROM compositions c
              JOIN clients cl ON cl.id=c.client_id""" + (" WHERE cl.release_id=?" if rid else "") +
              " GROUP BY c.generation,c.reason ORDER BY c.generation",p)]
            timeline=[dict(r) for r in con.execute("""SELECT substr(e.created_at,1,16) bucket,count(*) executions,
              sum(1-e.success) failures,round(1.0*sum(1-e.success)/count(*),4) failure_rate FROM executions e
              JOIN clients c ON c.id=e.client_id""" + (" WHERE c.release_id=?" if rid else "") +
              " GROUP BY bucket ORDER BY bucket",p)]
            effects=[]
            effect_rows=con.execute("""SELECT i.id implementation_id,sc.execution_cutoff,sf.release_id FROM status_changes sc
              JOIN implementations i ON i.pk=sc.implementation_pk JOIN spec_functions sf ON sf.id=i.spec_function_id
              WHERE sc.new_status='quarantined'""" + (" AND sf.release_id=?" if rid else "") + " ORDER BY sc.id",p).fetchall()
            for change in effect_rows:
                before=con.execute("""SELECT count(*),coalesce(sum(1-e.success),0) FROM executions e JOIN clients c ON c.id=e.client_id
                  WHERE c.release_id=? AND e.id<=?""",(change["release_id"],change["execution_cutoff"])).fetchone()
                after=con.execute("""SELECT count(*),coalesce(sum(1-e.success),0) FROM executions e JOIN clients c ON c.id=e.client_id
                  WHERE c.release_id=? AND e.id>?""",(change["release_id"],change["execution_cutoff"])).fetchone()
                effects.append({"implementation_id":change["implementation_id"],
                    "before_executions":before[0],"before_failure_rate":before[1]/before[0] if before[0] else 0,
                    "after_executions":after[0],"after_failure_rate":after[1]/after[0] if after[0] else 0})
            sequence=[]
            boundaries=[change["execution_cutoff"] for change in effect_rows]
            stages=[(None, None, boundaries[0] if boundaries else None)]
            stages.extend((change["implementation_id"],change["execution_cutoff"],
                           boundaries[index+1] if index+1 < len(boundaries) else None)
                          for index,change in enumerate(effect_rows))
            for implementation_id,start,end in stages:
                clauses=["c.release_id=?"] if rid else []
                stage_params=[rid] if rid else []
                if start is not None:
                    clauses.append("e.id>?"); stage_params.append(start)
                if end is not None:
                    clauses.append("e.id<=?"); stage_params.append(end)
                where=" WHERE " + " AND ".join(clauses) if clauses else ""
                measured=con.execute("""SELECT count(*),coalesce(sum(1-e.success),0)
                  FROM executions e JOIN clients c ON c.id=e.client_id"""+where,stage_params).fetchone()
                sequence.append({"implementation_id":implementation_id,"executions":measured[0],
                                 "healthy_rate":(measured[0]-measured[1])/measured[0] if measured[0] else None})
        release = self.release(rid) if rid is not None else None
        return {"release_id":rid,"release":release,"clients":clients,"spec_functions":specs,"implementations_per_function":counts,
                "theoretical_compositions":theoretical,"telemetry_events":events,"executions":executions[0],
                "failures":executions[1],"failure_rate":executions[1]/executions[0] if executions[0] else 0,
                "latest_execution_at":latest_execution_at,
                "observed_compositions":observed_compositions,
                "active_distribution":distributions,"implementation_stats":self.implementation_stats(rid),
                "pairwise_interactions":self.pairwise_stats(rid),"quarantined":quarantined,
                "recompositions":changes,"quarantine_effects":effects,"quarantine_sequence":sequence,
                "composition_history":history,"failure_timeline":timeline}

    def events(self, limit=100, rid=None):
        if rid is None:
            with self.db.connect() as con:
                latest=con.execute("SELECT id FROM releases ORDER BY id DESC LIMIT 1").fetchone()
            rid=latest["id"] if latest else None
        with self.db.connect() as con:
            rows=con.execute("""SELECT te.* FROM telemetry_events te JOIN clients c ON c.id=te.client_id""" +
                (" WHERE c.release_id=?" if rid else "") + " ORDER BY te.id DESC LIMIT ?",
                ((rid,limit) if rid else (limit,))).fetchall()
        return [{**dict(r),"recent_calls":json.loads(r["recent_calls"])} for r in rows]
