import os, sys, sqlite3
from typing import Optional, Any
from lib_py.agents.base import BaseAgentAdapter, DiscoveryContext
from lib_py.verify_session import workspace_key

class HermesAgentAdapter(BaseAgentAdapter):
    @property
    def name(self) -> str:
        return 'hermes'

    @property
    def own_key(self) -> str:
        return 'hermes_conversation_id_own'

    @property
    def ready_tokens(self) -> str:
        return 'Hermes|Welcome to Hermes Agent|NOUS HERMES'

    @property
    def exit_key(self) -> str:
        return '/exit'

    @property
    def delegate_agent_key(self) -> str:
        return 'hermes-agent'

    @property
    def identity_cache_fields(self) -> tuple:
        return ('session_id',)

    @property
    def input_prompt(self) -> str:
        return '❯'

    @property
    def input_placeholder(self) -> str:
        return ''

    @property
    def input_rule_pattern(self) -> str:
        return '─{10,}'

    def artifact_path(self, uuid: str, ctx: DiscoveryContext) -> str:
        return f"{ctx.home_dir}/.hermes/sessions/session_{uuid}.json"

    def verify_artifact(self, uuid: str, ctx: DiscoveryContext) -> bool:
        hdb = f"{ctx.home_dir}/.hermes/state.db"
        if not os.path.exists(hdb):
            return False
        try:
            conn = sqlite3.connect(hdb)
            r = conn.execute("SELECT cwd, started_at FROM sessions WHERE id=?", (uuid,)).fetchone()
            conn.close()
            if not r:
                return False
            found_cwd, started_at = r[0], r[1]
            if ctx.epoch and started_at and float(started_at) < float(ctx.epoch):
                return False
            if found_cwd and workspace_key(found_cwd) != workspace_key(ctx.cwd):
                return False
        except Exception:
            return False
        return True

    def purge_artifacts(self, uuid: str, ctx: DiscoveryContext) -> list:
        purged = []
        json_file = self.artifact_path(uuid, ctx)
        if os.path.exists(json_file):
            os.remove(json_file)
            purged.append(json_file)
        hdb = f"{ctx.home_dir}/.hermes/state.db"
        if os.path.exists(hdb):
            try:
                conn = sqlite3.connect(hdb)
                conn.execute("DELETE FROM sessions WHERE id=?", (uuid,))
                conn.execute("DELETE FROM messages WHERE session_id=?", (uuid,))
                conn.commit()
                conn.close()
                purged.append(f"db records for session: {uuid}")
            except Exception as e:
                sys.stderr.write(f"WARN: purge hermes db records failed: {e}\n")
        return purged

    def spawn_spec(self, binary: str, session_uuid: str = "", use_wrapper: bool = False) -> str:
        return f"{binary} --yolo --accept-hooks"

    def resume_spec(self, binary: str, session_uuid: str, materialized: bool = False) -> str:
        if materialized and session_uuid:
            return f"{binary} --resume {session_uuid} --no-restore-cwd --yolo --accept-hooks"
        return f"{binary} --yolo --accept-hooks"

    def auth_ok(self, run_cmd: Optional[Any] = None) -> bool:
        return True

    def discover(self, ctx: DiscoveryContext) -> list:
        hdb = f"{ctx.home_dir}/.hermes/state.db"
        if not os.path.exists(hdb):
            return []
        try:
            conn = sqlite3.connect(hdb)
            if ctx.epoch:
                rows = conn.execute(
                    "SELECT id FROM sessions WHERE cwd=? AND started_at >= ? ORDER BY started_at DESC LIMIT 20",
                    (ctx.workspace, ctx.epoch)
                ).fetchall()
            else:
                rows = conn.execute(
                    "SELECT id FROM sessions WHERE cwd=? ORDER BY started_at DESC LIMIT 20",
                    (ctx.workspace,)
                ).fetchall()
            conn.close()
            candidates = []
            for (cand,) in rows:
                if cand and self.verify_artifact(cand, ctx):
                    candidates.append(cand)
            return candidates
        except Exception:
            return []
