/**
 * Persistent store interface for the server-side KT log + address index.
 *
 * Append-only invariant: implementations MUST NEVER overwrite or delete a
 * row in the leaf table. The only mutation allowed is `appendLeaf`. Index
 * entries (`upsertIndex`, `tombstoneIndex`) replace in place because the
 * sorted index is a *projection* of the log — its history lives in the
 * log itself.
 */

import type { SignedTreeHead } from './sth.js';
import type { AddressIndexEntry } from './index-tree.js';

export interface KTLogLeaf {
  index: number;
  leafHash: Uint8Array;
  timestampMs: number;
  operation: number;
  address: string;
  bundleHash: Uint8Array;
}

export interface KTLogStore {
  /** Append a leaf. Returns assigned `index` (= prior size). */
  appendLeaf(input: Omit<KTLogLeaf, 'index'>): Promise<number>;

  /** Fetch leaves in [fromIndex, toIndex). For audit-path / consistency-proof builds. */
  getLeaves(fromIndex: number, toIndex: number): Promise<KTLogLeaf[]>;

  /** Fetch a single leaf. */
  getLeaf(index: number): Promise<KTLogLeaf | null>;

  /** Number of leaves currently in the log. */
  size(): Promise<number>;

  /** Upsert an address-index entry. */
  upsertIndexEntry(entry: AddressIndexEntry): Promise<void>;

  /** Tombstone an index entry (mark deleted). */
  tombstoneIndexEntry(address: string, latestLeafIndex: number): Promise<void>;

  /** Fetch the entire sorted index snapshot. */
  getAllIndexEntries(): Promise<AddressIndexEntry[]>;

  /** Fetch a single index entry by address. */
  getIndexEntry(address: string): Promise<AddressIndexEntry | null>;

  /** Persist a freshly-signed STH. */
  saveSTH(sth: SignedTreeHead): Promise<void>;

  /** Latest STH (most recent treeSize, most recent timestamp). */
  getLatestSTH(): Promise<SignedTreeHead | null>;

  /** STH at a specific tree size (for consistency proofs). */
  getSTHByTreeSize(treeSize: number): Promise<SignedTreeHead | null>;

  /** All STHs in (fromTimestamp, toTimestamp], sorted ascending. */
  listSTHs(fromTimestampMs?: number, toTimestampMs?: number): Promise<SignedTreeHead[]>;
}
