/**
 * @module storage/operationalModes
 * @description Operational modes that gate which operations a Brainy instance may
 * perform. Brainy's multi-process model runs one writer process plus any number of
 * reader processes against a single shared on-disk store; the mode object is the
 * in-process guard that enforces that contract.
 *
 * - {@link HybridMode} (the default, used by writer instances) permits reads,
 *   writes, and deletes — a writer must be able to read its own data.
 * - {@link ReaderMode} (used by `mode: 'reader'` / `Brainy.openReadOnly()` and by
 *   `asOf()` historical snapshots) permits reads only; every mutation throws.
 *
 * `validateOperation()` is called at the top of each mutation path, and the
 * `canWrite` flag drives the public read-only checks on the instance.
 */

/**
 * @description Base class for operational modes. Concrete modes declare which of
 * read/write/delete they permit; {@link BaseOperationalMode.validateOperation}
 * turns a disallowed operation into an explicit error.
 */
export abstract class BaseOperationalMode {
  abstract canRead: boolean
  abstract canWrite: boolean
  abstract canDelete: boolean

  /**
   * @description Throw if the requested operation is not allowed in this mode.
   * Called at the top of every mutation method so read-only instances fail loudly
   * rather than silently dropping writes.
   * @param operation - The operation being attempted.
   * @throws {Error} When the mode does not permit the operation.
   */
  validateOperation(operation: 'read' | 'write' | 'delete'): void {
    switch (operation) {
      case 'read':
        if (!this.canRead) {
          throw new Error('Read operations are not allowed in write-only mode')
        }
        break
      case 'write':
        if (!this.canWrite) {
          throw new Error('Write operations are not allowed in read-only mode')
        }
        break
      case 'delete':
        if (!this.canDelete) {
          throw new Error('Delete operations are not allowed in this mode')
        }
        break
    }
  }
}

/**
 * @description Read-only mode. Reads are permitted; writes and deletes throw.
 * Used by reader processes, `Brainy.openReadOnly()`, and historical snapshots.
 */
export class ReaderMode extends BaseOperationalMode {
  canRead = true
  canWrite = false
  canDelete = false
}

/**
 * @description Read-write mode and the default for writer instances. Permits
 * reads, writes, and deletes — a writer needs to read its own data.
 */
export class HybridMode extends BaseOperationalMode {
  canRead = true
  canWrite = true
  canDelete = true
}
