<?php

declare(strict_types=1);

namespace Drupal\flowdrop_stategraph\Exception;

use Drupal\flowdrop\Exception\FlowDropException;

/**
 * Exception thrown when checkpoint operations fail.
 *
 * This exception is thrown when:
 * - Checkpoint save fails.
 * - Checkpoint load fails.
 * - Checkpoint not found.
 * - Checkpoint data is corrupted.
 *
 * @api
 */
class CheckpointException extends FlowDropException {

  /**
   * Constructs a new CheckpointException.
   *
   * @param string $message
   *   The error message.
   * @param string|null $checkpointId
   *   The checkpoint ID involved (if any).
   * @param string|null $operation
   *   The operation that failed (get, put, list, delete).
   * @param \Throwable|null $previous
   *   Previous exception for chaining.
   */
  public function __construct(
    string $message,
    public readonly ?string $checkpointId = NULL,
    public readonly ?string $operation = NULL,
    ?\Throwable $previous = NULL,
  ) {
    $fullMessage = $message;

    if ($operation !== NULL) {
      $fullMessage = sprintf("[%s] %s", $operation, $message);
    }

    if ($checkpointId !== NULL) {
      $fullMessage .= sprintf(" (checkpoint: %s)", $checkpointId);
    }

    parent::__construct($fullMessage, 0, $previous);
  }

  /**
   * Creates an exception for checkpoint not found.
   *
   * @param string $checkpointId
   *   The checkpoint ID.
   *
   * @return self
   *   A new CheckpointException.
   */
  public static function notFound(string $checkpointId): self {
    return new self(
      message: "Checkpoint not found",
      checkpointId: $checkpointId,
      operation: "get",
    );
  }

  /**
   * Creates an exception for save failure.
   *
   * @param string $checkpointId
   *   The checkpoint ID.
   * @param \Throwable|null $previous
   *   Previous exception.
   *
   * @return self
   *   A new CheckpointException.
   */
  public static function saveFailed(string $checkpointId, ?\Throwable $previous = NULL): self {
    return new self(
      message: "Failed to save checkpoint",
      checkpointId: $checkpointId,
      operation: "put",
      previous: $previous,
    );
  }

}
