/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import type { RuntimeEvent } from './runtime-event.js';
import { runtimeHandoffPause } from './runtime-handoff.js';
import {
  mayBeTranscriptLedgerInvocationId,
  type RuntimeInvocationRecord,
} from './runtime-invocation.js';
import type {
  ContinuationClaimV1,
  ImmutableRuntimePrefixV1,
  RuntimeBoundaryDigest,
} from './runtime-boundary.js';
import type {
  WorkspaceEpochRecordV1,
  WorkspaceHeadRecordV1,
  WorkspaceProjectionRebuildResult,
  WorkspaceVersionRecordV1,
} from './workspace-version-authority.js';
import { WORKSPACE_VERSION_AUTHORITY_CAPABILITY_V1 } from './workspace-version-authority.js';

export const TOOL_RECOVERY_BUNDLE_CAPABILITY_V1 = 'tool_recovery_bundle_v1' as const;
export const RUNTIME_CONTINUATION_AUTHORITY_V1 = 'runtime_continuation_authority_v1' as const;

export interface RuntimeRecoveryBundleCommit {
  operationId: string;
  reconcileRuntimeEvent: RuntimeEvent;
  outcomeRuntimeEvent?: RuntimeEvent;
  decisionRuntimeEvent: RuntimeEvent;
}

export interface RuntimeInvocationRecoveryInventoryEntry {
  readonly sessionId: string;
  readonly invocationId: string;
  /**
   * Settled invocations normally need no further fields. Identity is retained
   * only when the persisted id could belong to transcript conversion and the
   * runtime must apply its exact deterministic-id check.
   */
  readonly identity?: Pick<
    RuntimeInvocationRecord,
    'sessionId' | 'invocationId' | 'runId' | 'turnId' | 'openedAt'
  >;
  /** Present only when recovery must inspect this invocation's full evidence. */
  readonly candidate?: RuntimeInvocationRecord;
}

export function runtimeInvocationRecoveryInventoryFromInvocations(
  invocations: readonly RuntimeInvocationRecord[],
): RuntimeInvocationRecoveryInventoryEntry[] {
  return invocations.map((invocation) => {
    const base = {
      sessionId: invocation.sessionId,
      invocationId: invocation.invocationId,
    };
    if (!invocation.terminalEvent || runtimeHandoffPause(invocation.terminalEvent)) {
      return { ...base, candidate: invocation };
    }
    return mayBeTranscriptLedgerInvocationId(invocation.invocationId)
      ? {
          ...base,
          identity: {
            sessionId: invocation.sessionId,
            invocationId: invocation.invocationId,
            runId: invocation.runId,
            turnId: invocation.turnId,
            openedAt: invocation.openedAt,
          },
        }
      : base;
  });
}

/**
 * An append arrived after the run's terminal fact was already written. The
 * refusal is the store doing its job: once a run has said it ended, a late
 * stream event is by definition not part of it. Typed so callers can tell
 * this expected boundary apart from store failure (#2311): pressing stop
 * seals the run ahead of the still-draining stream, and the stragglers that
 * window refuses must not read as "the store is sick".
 */
export class RunSealedError extends Error {
  readonly name = 'RunSealedError';

  constructor(readonly runId: string) {
    super(`RuntimeEvent run ${runId} is sealed by its terminal fact`);
  }
}

/** A requested stable-storage barrier failed; read-back cannot upgrade it to success. */
export class DurableStoreWriteError extends Error {
  readonly name = 'DurableStoreWriteError';

  constructor(
    message: string,
    readonly storeCause: unknown,
  ) {
    super(message);
  }
}

export interface RuntimeEventStore {
  /** Canonical stores fail the active run closed on every durable write error. */
  readonly durability?: 'best_effort' | 'canonical';
  /**
   * Enumerate a Session's invocations from the canonical events.
   *
   * This is a query, not a table. Nothing writes it and nothing repairs it, so
   * clearing any physical index and rebuilding from the events produces the
   * same inventory. Reserved control-plane invocation streams have no opening
   * fact and therefore never appear here.
   *
   * One exception, and it is a durable one: an invocation that predates the
   * opening fact could not be given one without rewriting an immutable
   * sequence, so a store that migrated such a Session keeps that opening
   * outside the events and merges it in here. Those invocations cannot be
   * rebuilt from events alone, and never will be.
   *
   * An invocation's `terminalEvent` is its first terminal event. Sealing makes
   * that the only one for anything written through this interface; a ledger
   * from before the seal can carry a straggler after it, and the ending is
   * still the terminal event.
   */
  listSessionInvocations(sessionId: string): Promise<RuntimeInvocationRecord[]>;
  /**
   * Narrow startup inventory. Every opening contributes a minimal existence
   * marker. Full identity is retained only for transcript-namespace ambiguity;
   * opening and terminal payloads are decoded only for unfinished invocations
   * and durable handoff pauses that recovery must inspect.
   */
  listInvocationRecoveryInventory?(
    sessionIds: readonly string[],
  ): Promise<RuntimeInvocationRecoveryInventoryEntry[]>;
  /**
   * One invocation by run id, absent when no opening fact names it. A store
   * that indexes openings answers this in one read; stores without the fast
   * path are answered from the inventory by `readRunInvocation`.
   */
  readRunInvocation?(
    sessionId: string,
    runId: string,
  ): Promise<RuntimeInvocationRecord | undefined>;
  /**
   * Append one event to a run.
   *
   * Every implementation seals: once a run holds a terminal event, appending
   * any event the store does not already have must throw `RunSealedError`. An
   * exact-id replay of an event already stored stays idempotent. This is what
   * makes a run's ending single and final, so it is an obligation of this
   * interface rather than a detail of one store — a test double that skips it
   * is manufacturing a ledger no supported store can produce. Tests that need a
   * corrupt ledger should build it beneath this interface, not through it.
   */
  appendRuntimeEvent(
    sessionId: string,
    runId: string,
    event: RuntimeEvent,
    options?: { durable?: boolean },
  ): Promise<void>;
  /**
   * Coalesce one already-admitted mutable presentation stream into one store
   * transaction. Callers must preserve provider order and flush before every
   * immutable execution boundary. Stores that do not implement this optional
   * fast path continue to receive one append per partial event. The seal on
   * `appendRuntimeEvent` applies here too.
   */
  appendRuntimePartialBatch?(
    sessionId: string,
    runId: string,
    events: readonly RuntimeEvent[],
  ): Promise<void>;
  /**
   * Append the terminal event if absent, or re-establish its stable-storage
   * barrier if present. This is the one writer the seal admits: it must commit
   * the terminal event and the seal check in the same transaction, so two
   * callers racing to end one run produce one terminal event and a
   * `RunSealedError` for the loser.
   */
  ensureTerminalRuntimeEventDurable(
    sessionId: string,
    runId: string,
    event: RuntimeEvent,
  ): Promise<void>;
  /**
   * Recovery-only terminal barrier for a T1-without-T2 run. The writer must
   * commit the terminal fact and settle exactly these dispatched operations in
   * one transaction; an ordinary terminal append still rejects them.
   */
  ensureRecoveredTerminalRuntimeEventDurable?(
    sessionId: string,
    runId: string,
    event: RuntimeEvent,
    unsettledOperationIds: readonly string[],
  ): Promise<void>;
  readRuntimeEvents(sessionId: string, runId: string): Promise<RuntimeEvent[]>;
  /** Session-wide immutable append order. */
  readSessionRuntimeEventEntries(
    sessionId: string,
  ): Promise<Array<{ readonly ordinal: number; readonly event: RuntimeEvent }>>;
  /** Physical append-log rows only; excludes mutable partial snapshots. */
  readImmutableRuntimeEvents?(sessionId: string, runId: string): Promise<RuntimeEvent[]>;
  /** Versioned physical prefix with event-seq high-water and canonical digest. */
  readImmutableRuntimePrefix?(input: {
    sessionId: string;
    runId: string;
    upToEventSeq?: number;
  }): Promise<ImmutableRuntimePrefixV1>;
  readSessionRuntimeEvents(sessionId: string): Promise<RuntimeEvent[]>;
  /**
   * Renumber a Session's event ordinals in the order its invocations opened.
   *
   * Ordinals are minted at append time, which is the conversation's order for
   * every run this build starts. It is not the order of a run converted from
   * the legacy transcript: that turn was said before runs already on the
   * ledger, and it is appended after them. The transcript conversion is the
   * only caller and the only writer that can know this, and it runs while the
   * Session still has no ordinal reader, so these numbers are recomputed
   * rather than moved out from under anyone.
   */
  resequenceSessionEventOrdinals(sessionId: string): Promise<void>;
  /**
   * Recall's narrowing over the ledger: the Sessions among `sessionIds` whose
   * event payloads contain one of the folded `terms`, plus every Session with
   * an in-flight partial stream. A superset of the Sessions that project a
   * matching message — the caller projects each one and re-runs the real
   * predicate. Stores without this fast path leave recall to read every
   * transcript.
   */
  listSessionsWithRuntimeEventText?(
    sessionIds: readonly string[],
    terms: readonly string[],
  ): Promise<string[]>;
  /** Events of kinds that project to searchable messages, for recall's idf term. */
  countRuntimeEventMessages?(sessionIds: readonly string[]): Promise<number>;
}

/** One invocation by run id, through the store's fast path when it has one. */
export async function readRunInvocation(
  store: Pick<RuntimeEventStore, 'listSessionInvocations' | 'readRunInvocation'>,
  sessionId: string,
  runId: string,
): Promise<RuntimeInvocationRecord | undefined> {
  if (store.readRunInvocation) return store.readRunInvocation(sessionId, runId);
  return (await store.listSessionInvocations(sessionId)).find(
    (invocation) => invocation.runId === runId,
  );
}

export interface RuntimeRecoveryBundleStore extends RuntimeEventStore {
  readonly recoveryBundleCapability: typeof TOOL_RECOVERY_BUNDLE_CAPABILITY_V1;
  commitToolRecoveryBundle(input: RuntimeRecoveryBundleCommit): Promise<void>;
}

export type ContinuationClaimResult =
  | { kind: 'acquired'; claim: ContinuationClaimV1 }
  | { kind: 'existing'; claim: ContinuationClaimV1 }
  | { kind: 'conflict'; claim: ContinuationClaimV1 };

export interface ContinuationClaimStateV1 {
  claim: ContinuationClaimV1;
  startEventId?: string;
  /** Store-owned classification of the narrow command that committed event 1. */
  startKind?: 'runtime_admission' | 'claim_repair';
}

export interface RuntimeContinuationAuthorityStore extends RuntimeEventStore {
  readonly continuationAuthorityCapability: typeof RUNTIME_CONTINUATION_AUTHORITY_V1;
  readImmutableRuntimeEvents(sessionId: string, runId: string): Promise<RuntimeEvent[]>;
  readImmutableRuntimePrefix(input: {
    sessionId: string;
    runId: string;
    upToEventSeq?: number;
  }): Promise<ImmutableRuntimePrefixV1>;
  claimContinuation(input: { claim: ContinuationClaimV1 }): Promise<ContinuationClaimResult>;
  readContinuationClaimByBoundary(
    boundaryDigest: RuntimeBoundaryDigest,
  ): Promise<ContinuationClaimV1 | undefined>;
  readContinuationClaimStateByBoundary(
    boundaryDigest: RuntimeBoundaryDigest,
  ): Promise<ContinuationClaimStateV1 | undefined>;
  /** Unsettled claim targets among the selected Sessions, for restart recovery. */
  listUnsettledContinuationClaimsForRecovery?(
    sessionIds: readonly string[],
  ): Promise<ContinuationClaimStateV1[]>;
  listContinuationClaimsForRecovery(sessionId: string): Promise<ContinuationClaimStateV1[]>;
  commitContinuationStart(input: {
    claim: ContinuationClaimV1;
    event: RuntimeEvent;
  }): Promise<{ created: boolean; runtimeEventSeq: number }>;
  commitContinuationRepairStart(input: {
    claim: ContinuationClaimV1;
    event: RuntimeEvent;
  }): Promise<{ created: boolean; runtimeEventSeq: number }>;
}

export interface RuntimeWorkspaceVersionAuthorityStore extends RuntimeEventStore {
  readonly workspaceVersionAuthorityCapability: typeof WORKSPACE_VERSION_AUTHORITY_CAPABILITY_V1;
  readWorkspaceEpoch(
    workspaceId: string,
    workspaceEpochId: string,
  ): Promise<WorkspaceEpochRecordV1 | undefined>;
  readWorkspaceVersion(workspaceVersionId: string): Promise<WorkspaceVersionRecordV1 | undefined>;
  readWorkspaceHead(
    workspaceId: string,
    workspaceEpochId: string,
  ): Promise<WorkspaceHeadRecordV1 | undefined>;
  rebuildWorkspaceVersionProjections(): Promise<WorkspaceProjectionRebuildResult>;
}
