<?php

declare(strict_types=1);

namespace Drupal\flowdrop_node_type\Service;

use Drupal\flowdrop_node_type\FlowDropNodeTypeInterface;

/**
 * Outcome of generating a single node type from a workflow node.
 *
 * @internal This class is not part of the public API and may change without
 *   notice.
 */
final class NodeTypeGenerationResult {

  /**
   * A new node type entity was created.
   */
  public const CREATED = 'created';

  /**
   * A node type with this id already existed; nothing was written.
   */
  public const SKIPPED = 'skipped';

  /**
   * The node type could not be generated; see reasons.
   */
  public const REJECTED = 'rejected';

  /**
   * Constructs a NodeTypeGenerationResult.
   *
   * @param string $status
   *   One of CREATED, SKIPPED, REJECTED.
   * @param string $nodeTypeId
   *   The node type id this result concerns.
   * @param \Drupal\flowdrop_node_type\FlowDropNodeTypeInterface|null $entity
   *   The created or pre-existing entity, or NULL when rejected.
   * @param array<int, string> $reasons
   *   Why generation was rejected (empty unless REJECTED).
   * @param array<int, string> $warnings
   *   Non-blocking notes (e.g. a file default dropped for type mismatch).
   */
  private function __construct(
    public readonly string $status,
    public readonly string $nodeTypeId,
    public readonly ?FlowDropNodeTypeInterface $entity = NULL,
    public readonly array $reasons = [],
    public readonly array $warnings = [],
  ) {}

  /**
   * Creates a "created" result.
   *
   * @param string $nodeTypeId
   *   The generated node type id.
   * @param \Drupal\flowdrop_node_type\FlowDropNodeTypeInterface $entity
   *   The created entity.
   * @param array<int, string> $warnings
   *   Non-blocking notes.
   */
  public static function created(string $nodeTypeId, FlowDropNodeTypeInterface $entity, array $warnings = []): self {
    return new self(self::CREATED, $nodeTypeId, $entity, [], $warnings);
  }

  /**
   * Creates a "skipped" result (entity already present).
   *
   * @param string $nodeTypeId
   *   The pre-existing node type id.
   * @param \Drupal\flowdrop_node_type\FlowDropNodeTypeInterface $entity
   *   The pre-existing entity.
   */
  public static function skipped(string $nodeTypeId, FlowDropNodeTypeInterface $entity): self {
    return new self(self::SKIPPED, $nodeTypeId, $entity);
  }

  /**
   * Creates a "rejected" result.
   *
   * @param string $nodeTypeId
   *   The node type id that could not be generated.
   * @param array<int, string> $reasons
   *   Why generation was rejected.
   */
  public static function rejected(string $nodeTypeId, array $reasons): self {
    return new self(self::REJECTED, $nodeTypeId, NULL, array_values($reasons));
  }

  /**
   * Whether a node type entity exists after this operation.
   *
   * True when the node type was created or was already present.
   */
  public function isResolved(): bool {
    return $this->status === self::CREATED || $this->status === self::SKIPPED;
  }

}
