<?php

declare(strict_types=1);

namespace Drupal\flowdrop_workflow\Diagnostic;

use Drupal\Core\StringTranslation\TranslatableMarkup;

/**
 * Diagnoses one class of workflow problems and translates remedies to edits.
 *
 * A diagnostic is a thin adapter over an existing detector (the validator, the
 * drift detector, …): it does not re-implement detection. Its two jobs are to
 * turn that detector's output into {@see Finding}s carrying
 * {@see RemedyOption}s with *stable* locators, and — given a user's choice — to
 * rebuild the mutation primitives ({@see Mutation\WorkflowMutationInterface})
 * server-side, never trusting a client-supplied payload.
 *
 * Implementations are tagged services ('flowdrop_workflow.diagnostic')
 * collected by the {@see \Drupal\flowdrop_workflow\Service\WorkflowDoctor} via
 * a !tagged_iterator, receiving their detector dependencies by normal DI.
 *
 * @api
 */
interface WorkflowDiagnosticInterface {

  /**
   * The stable diagnostic id (e.g. 'validator', 'drift').
   *
   * @return string
   *   A short, stable identifier, unique across diagnostics.
   */
  public function id(): string;

  /**
   * A human-readable label for grouping in the UI.
   *
   * @return \Drupal\Core\StringTranslation\TranslatableMarkup
   *   The label.
   */
  public function label(): TranslatableMarkup;

  /**
   * Diagnoses the workflow, returning findings with their offered remedies.
   *
   * @param \Drupal\flowdrop_workflow\Diagnostic\DiagnosticContext $context
   *   The working set (the stored workflow plus shared indexes).
   *
   * @return list<\Drupal\flowdrop_workflow\Diagnostic\Finding>
   *   The findings this diagnostic produced (possibly empty).
   */
  public function diagnose(DiagnosticContext $context): array;

  /**
   * Rebuilds the mutations for a chosen remedy, server-side.
   *
   * Derived afresh from the finding and the live context — the client never
   * sends mutations. Returns an empty array when the remedy resolves to no
   * change (e.g. the targeted element already vanished).
   *
   * @param \Drupal\flowdrop_workflow\Diagnostic\Finding $finding
   *   The finding the remedy applies to (from a fresh diagnose()).
   * @param string $remedyId
   *   The chosen remedy id.
   * @param array<string, mixed> $params
   *   The user's decisions for the remedy (e.g. the chosen node type id).
   * @param \Drupal\flowdrop_workflow\Diagnostic\DiagnosticContext $context
   *   The working set.
   *
   * @return list<\Drupal\flowdrop_workflow\Diagnostic\Mutation\WorkflowMutationInterface>
   *   The mutations to apply for this remedy.
   */
  public function buildMutations(Finding $finding, string $remedyId, array $params, DiagnosticContext $context): array;

}
