import { SqliteConnection } from "./internal/connection.js";
import { migrate as applyMigrations } from "./internal/migrate.js";
import { AuditRepository } from "./repositories/auditRepository.js";
import { DebugRevealRepository } from "./repositories/debugRevealRepository.js";
import { OnboardingRepository } from "./repositories/onboardingRepository.js";
import { OutboxRepository } from "./repositories/outboxRepository.js";
import { PermissionActivityRepository } from "./repositories/permissionActivityRepository.js";
import { PermissionDecisionRepository } from "./repositories/permissionDecisionRepository.js";
import { PermissionRequestRepository } from "./repositories/permissionRequestRepository.js";
import { RepositoryBindingRepository, } from "./repositories/repositoryBindingRepository.js";
import { ReviewQueueRepository } from "./repositories/reviewQueueRepository.js";
import { RunEvidenceRepository } from "./repositories/runEvidenceRepository.js";
import { RunRepository } from "./repositories/runRepository.js";
import { RuntimeEventRepository } from "./repositories/runtimeEventRepository.js";
import { SettingsReadinessRepository } from "./repositories/settingsReadinessRepository.js";
import { SyncStateRepository } from "./repositories/syncStateRepository.js";
import { WorkspaceRepository } from "./repositories/workspaceRepository.js";
import { DeviceRepository } from "./repositories/deviceRepository.js";
import { CommandInboxRepository } from "./repositories/commandInboxRepository.js";
import { RemoteControlPolicyRepository } from "./repositories/remoteControlPolicyRepository.js";
export * from "../domain/index.js";
export class LocalSqliteStore {
    dbPath;
    #db;
    #workspace;
    #run;
    #runEvidence;
    #runtimeEvent;
    #outbox;
    #repositoryBinding;
    #onboarding;
    #settingsReadiness;
    #reviewQueue;
    #syncState;
    #debugReveal;
    #permissionActivity;
    #permissionRequest;
    #permissionDecision;
    #audit;
    #device;
    #commandInbox;
    #remoteControlPolicy;
    constructor(dbPath, db) {
        this.dbPath = dbPath;
        this.#db = db;
        this.#workspace = new WorkspaceRepository(db);
        this.#run = new RunRepository(db);
        this.#runEvidence = new RunEvidenceRepository(db);
        this.#runtimeEvent = new RuntimeEventRepository(db);
        this.#outbox = new OutboxRepository(db);
        this.#repositoryBinding = new RepositoryBindingRepository(db);
        this.#onboarding = new OnboardingRepository(db);
        this.#settingsReadiness = new SettingsReadinessRepository(db);
        this.#reviewQueue = new ReviewQueueRepository(db);
        this.#syncState = new SyncStateRepository(db);
        this.#device = new DeviceRepository(db);
        this.#commandInbox = new CommandInboxRepository(db);
        this.#remoteControlPolicy = new RemoteControlPolicyRepository(db);
        this.#debugReveal = new DebugRevealRepository(db);
        this.#permissionActivity = new PermissionActivityRepository(db);
        this.#permissionRequest = new PermissionRequestRepository(db, this.#permissionActivity);
        this.#permissionDecision = new PermissionDecisionRepository(db, this.#permissionActivity);
        this.#audit = new AuditRepository(db);
        this.migrate();
    }
    static async open(dbPath) {
        return LocalSqliteStore.openSync(dbPath);
    }
    static openSync(dbPath) {
        return new LocalSqliteStore(dbPath, SqliteConnection.open(dbPath));
    }
    close() {
        this.#db.close();
    }
    status() {
        return {
            backend: "sqlite",
            path: this.dbPath,
            schemaVersion: this.#db.schemaVersion(),
            counts: {
                workspaces: this.#db.count("workspaces"),
                runs: this.#db.count("runs"),
                runtimeEvents: this.#db.count("runtime_events"),
                pendingPermissionRequests: this.#db.count("permission_requests", "status = 'pending'"),
                pendingOutboxEvents: this.#db.count("outbox_events", "status = 'pending'"),
            },
        };
    }
    migrate() {
        applyMigrations(this.#db, () => {
            this.#permissionActivity.backfillPermissionActivityEvents();
        });
    }
    upsertWorkspace(input) {
        return this.#workspace.upsertWorkspace(input);
    }
    findWorkspace(id) {
        return this.#workspace.findWorkspace(id);
    }
    listWorkspaceIds(limit = 200) {
        return this.#workspace.listWorkspaceIds(limit);
    }
    createRun(input) {
        return this.#run.createRun(input);
    }
    updateRunRuntimeSession(id, runtimeSessionId) {
        return this.#run.updateRunRuntimeSession(id, runtimeSessionId);
    }
    updateRunStatus(id, status, lastError) {
        return this.#run.updateRunStatus(id, status, lastError);
    }
    getRun(id) {
        return this.#run.getRun(id);
    }
    findRun(id) {
        return this.#run.findRun(id);
    }
    listRunsForWorkspace(workspaceId, limit = 100) {
        return this.#run.listRunsForWorkspace(workspaceId, limit);
    }
    upsertRepositoryBinding(input) {
        this.#repositoryBinding.upsertRepositoryBinding(input);
    }
    updateRepositoryWorkingCopy(input) {
        return this.#repositoryBinding.updateRepositoryWorkingCopy(input);
    }
    deleteRepositoryBinding(workspaceId, id) {
        return this.#repositoryBinding.deleteRepositoryBinding(workspaceId, id);
    }
    findRepositoryBinding(workspaceId, id) {
        return this.#repositoryBinding.findRepositoryBinding(workspaceId, id);
    }
    listRepositoryBindings(workspaceId) {
        return this.#repositoryBinding.listRepositoryBindings(workspaceId);
    }
    upsertOnboardingGate(input) {
        this.#onboarding.upsertOnboardingGate(input);
    }
    listOnboardingGates(workspaceId) {
        return this.#onboarding.listOnboardingGates(workspaceId);
    }
    upsertSettingsReadiness(input) {
        this.#settingsReadiness.upsertSettingsReadiness(input);
    }
    listSettingsReadiness(workspaceId) {
        return this.#settingsReadiness.listSettingsReadiness(workspaceId);
    }
    upsertReviewQueueEntry(input) {
        this.#reviewQueue.upsertReviewQueueEntry(input);
    }
    listReviewQueue(workspaceId) {
        return this.#reviewQueue.listReviewQueue(workspaceId);
    }
    insertReviewDecision(input) {
        this.#reviewQueue.insertReviewDecision(input);
    }
    listReviewDecisions(workspaceId) {
        return this.#reviewQueue.listReviewDecisions(workspaceId);
    }
    recordSyncAttempt(input) {
        this.#syncState.recordSyncAttempt(input);
    }
    findSyncState(domain, idempotencyKey) {
        return this.#syncState.findSyncState(domain, idempotencyKey);
    }
    listSyncStateForDomain(domain) {
        return this.#syncState.listSyncStateForDomain(domain);
    }
    // Device identity
    registerDevice(input) {
        return this.#device.registerDevice(input);
    }
    /**
     * Ensures a device row exists for a pairing claim, keyed on the browser-
     * supplied device id, so recordDevicePairing actually persists (GAP 2). The
     * device's workspace_id FK is satisfied by upserting a workspace shell first
     * (non-destructive: an existing workspace's root_path is unchanged when the
     * pairing supplies none). Idempotent — re-pairing keeps the original row.
     */
    ensureDeviceForPairing(input) {
        const existingWorkspace = this.#workspace.findWorkspace(input.workspaceId);
        this.#workspace.upsertWorkspace({
            id: input.workspaceId,
            rootPath: existingWorkspace?.rootPath ?? "",
        });
        return this.#device.ensureDeviceForPairing(input);
    }
    findDevice(id) {
        return this.#device.findDevice(id);
    }
    findDeviceByWorkspace(workspaceId) {
        return this.#device.findDeviceByWorkspace(workspaceId);
    }
    listDevices() {
        return this.#device.listDevices();
    }
    updateDeviceLabel(id, label) {
        return this.#device.updateDeviceLabel(id, label);
    }
    recordDevicePairing(input) {
        return this.#device.recordPairing(input);
    }
    // Command inbox
    receiveCommand(input) {
        return this.#commandInbox.receiveCommand(input);
    }
    commandExists(commandId) {
        return this.#commandInbox.exists(commandId);
    }
    findCommand(commandId) {
        return this.#commandInbox.findCommand(commandId);
    }
    listPendingCommands() {
        return this.#commandInbox.listPending();
    }
    listAwaitingConfirmationCommands() {
        return this.#commandInbox.listAwaitingConfirmation();
    }
    markCommandProcessed(commandId) {
        this.#commandInbox.markProcessed(commandId);
    }
    markCommandFailed(commandId, reason) {
        this.#commandInbox.markFailed(commandId, reason);
    }
    markCommandAwaitingConfirmation(commandId) {
        this.#commandInbox.markAwaitingConfirmation(commandId);
    }
    claimRemoteCommand(rcaCommandId, inboxCommandId) {
        this.#commandInbox.claimRemoteCommand(rcaCommandId, inboxCommandId);
    }
    isRemoteCommandReplay(rcaCommandId, inboxCommandId) {
        return this.#commandInbox.isRemoteCommandReplay(rcaCommandId, inboxCommandId);
    }
    // Remote Control policy (Layer 3 default-deny)
    getRemoteControlPolicy(workspaceId, category) {
        return this.#remoteControlPolicy.get(workspaceId, category);
    }
    setRemoteControlPolicy(workspaceId, row) {
        this.#remoteControlPolicy.set(workspaceId, row);
    }
    listRemoteControlPolicy(workspaceId) {
        return this.#remoteControlPolicy.listForWorkspace(workspaceId);
    }
    getRunByRuntimeSessionId(runtimeSessionId) {
        return this.#run.getRunByRuntimeSessionId(runtimeSessionId);
    }
    upsertRunEvidence(input) {
        return this.#runEvidence.upsertRunEvidence(input);
    }
    getRunEvidence(runId) {
        return this.#runEvidence.getRunEvidence(runId);
    }
    findRunEvidence(runId) {
        return this.#runEvidence.findRunEvidence(runId);
    }
    appendRuntimeEvent(input) {
        return this.#runtimeEvent.appendRuntimeEvent(input);
    }
    listRuntimeEventsForRun(runId, options = {}) {
        return this.#runtimeEvent.listRuntimeEventsForRun(runId, options);
    }
    upsertPermissionRequest(input) {
        return this.#permissionRequest.upsertPermissionRequest(input);
    }
    findPermissionRequest(id) {
        return this.#permissionRequest.findPermissionRequest(id);
    }
    insertPermissionDecision(input) {
        return this.#permissionDecision.insertPermissionDecision(input);
    }
    findPermissionDecision(id) {
        return this.#permissionDecision.findPermissionDecision(id);
    }
    listPermissionDecisions(options) {
        return this.#permissionDecision.listPermissionDecisions(options);
    }
    listActivePermissionDecisionsForPolicy() {
        return this.#permissionDecision.listActivePermissionDecisionsForPolicy();
    }
    revokePermissionDecision(input) {
        return this.#permissionDecision.revokePermissionDecision(input);
    }
    listPermissionActivity(options) {
        return this.#permissionActivity.listPermissionActivity(options);
    }
    listPermissionRequests(options = {}) {
        return this.#permissionRequest.listPermissionRequests(options);
    }
    claimPermissionRequestForReply(id) {
        return this.#permissionRequest.claimPermissionRequestForReply(id);
    }
    markPermissionRequestAnswered(input) {
        return this.#permissionRequest.markPermissionRequestAnswered(input);
    }
    markPermissionRequestReplyFailed(id, lastError, selectedOption, opencodeReply) {
        return this.#permissionRequest.markPermissionRequestReplyFailed(id, lastError, selectedOption, opencodeReply);
    }
    appendOutboxEvent(input) {
        return this.#outbox.appendOutboxEvent(input);
    }
    listPendingOutboxEvents(limit = 100) {
        return this.#outbox.listPendingOutboxEvents(limit);
    }
    appendDebugRevealEvent(input) {
        return this.#debugReveal.appendDebugRevealEvent(input);
    }
    getDebugRevealStatus(input) {
        return this.#debugReveal.getDebugRevealStatus(input);
    }
    listDebugRevealEvents(workspaceId) {
        return this.#debugReveal.listDebugRevealEvents(workspaceId);
    }
    appendAuditEvent(event) {
        return this.#audit.appendAuditEvent(event);
    }
    listAuditEvents() {
        return this.#audit.listAuditEvents();
    }
    listCommandAuditEvents(limit) {
        return this.#audit.listCommandAuditEvents(limit);
    }
}
