package cloud.nstart.terravault.ordinis.restapi.service.reference;

/**
 * Поведение при попытке закрыть source record на который ссылаются другие
 * (через JSON Schema marker {@code x-references-on-close}).
 *
 * <p>Значение объявляется в schema рядом с {@code x-references}:
 * <pre>
 * {
 *   "satelliteTypeCode": {
 *     "type": "string",
 *     "x-references": "satellite_type.code",
 *     "x-references-on-close": "block"
 *   }
 * }
 * </pre>
 *
 * <p>Каждое значение enum описывает что произойдёт когда пользователь пытается
 * close (или _bulk_close) запись в target словаре, на которую есть active
 * referencing records:
 *
 * <ul>
 *   <li>{@link #BLOCK} (default) — close отклоняется с 409 + список dependents.
 *       Совместимо с текущим v1 поведением: dangling FK не появляются.</li>
 *   <li>{@link #WARN} — close проходит, но в response body возвращается
 *       {@code warnings[]} с количеством affected referencing records.
 *       Orphan scanner потом подхватит их в metric.</li>
 *   <li>{@link #CASCADE} — close source ⇒ atomic close всех direct dependents
 *       в одной transaction. One hop по design (F.OUT). N{@code >}1 hop требует
 *       multi-step orchestration — позже.</li>
 * </ul>
 *
 * <p>Default = {@link #BLOCK} применяется если schema не объявляет
 * {@code x-references-on-close} (включая legacy bundle{@code <}=v1.2.1).
 * Phase 1 prep commit вводит этот enum + parsing — runtime semantics
 * (актуальный cascade engine) добавляются Phase 3.
 */
public enum OnCloseAction {
  /** Default. Reject close with 409 + dependents list. Backward-compat с v1. */
  BLOCK,

  /** Allow close, emit warnings[] в response body, дальше orphan scanner. */
  WARN,

  /** Atomic cascade close direct dependents в той же transaction (1 hop). */
  CASCADE;

  /**
   * Lenient parser: case-insensitive, whitespace-trimmed, null/blank → BLOCK.
   * Unknown value → IllegalArgumentException (validated на bundle import,
   * не runtime — см. design doc § Cascade rules).
   */
  public static OnCloseAction fromString(String value) {
    if (value == null) return BLOCK;
    String normalized = value.trim();
    if (normalized.isEmpty()) return BLOCK;
    for (OnCloseAction a : values()) {
      if (a.name().equalsIgnoreCase(normalized)) return a;
    }
    throw new IllegalArgumentException(
        "x-references-on-close must be one of [block, warn, cascade], got: " + value);
  }
}
