<?php
/**
 * Get-sync-job result value object.
 *
 * Phase 11 slice 11e-A immutable VO that wraps the §11.4
 * `GET /clb/v1/sync/jobs/{id}` response `data` shape documented in
 * `specifications/rest-api-spec.md`. The §11.4 surface returns the
 * §6.5 `SyncJob` shape (already wire-projected by
 * {@see ListSyncJobsUseCase::projectJob()} — DB `pending` →
 * wire `queued` per §6.0) plus two optional correlation fields
 * extracted from the record's `payload_json` blob:
 *
 *   - `correlation_id`: cross-request series identifier used to
 *     trace a logical operation across multiple jobs / requests.
 *   - `parent_request_id`: identifier of the originating request
 *     that enqueued this job.
 *
 * Both correlation axes are nullable: a job that was enqueued
 * without a correlation envelope (e.g. via WP-CLI or a periodic
 * sweep) carries null values for both fields.
 *
 * @package CommerceLinkBuilder\Application\SyncJobs\UseCase
 */

declare(strict_types=1);

namespace CommerceLinkBuilder\Application\SyncJobs\UseCase;

/**
 * Immutable result of {@see GetSyncJobUseCase::execute()}.
 *
 * See the file-level docblock for the §11.4 envelope shape and
 * the relationship between the `job` projection and the two
 * correlation axes extracted from the record's payload.
 */
final class GetSyncJobResult {

	/**
	 * Wire-projected §6.5 `SyncJob` shape produced by
	 * {@see ListSyncJobsUseCase::projectJob()}.
	 *
	 * @var array<string, mixed>
	 */
	private array $job;

	/**
	 * Cross-request correlation identifier extracted from the
	 * record's payload, or null when absent.
	 */
	private ?string $correlationId;

	/**
	 * Originating-request identifier extracted from the record's
	 * payload, or null when absent.
	 */
	private ?string $parentRequestId;

	/**
	 * Construct the result with explicit values for every axis.
	 *
	 * @param array<string, mixed> $job             Wire-projected §6.5 `SyncJob`.
	 * @param string|null          $correlationId   Correlation series id.
	 * @param string|null          $parentRequestId Originating request id.
	 */
	public function __construct(
		array $job,
		?string $correlationId,
		?string $parentRequestId
	) {
		$this->job             = $job;
		$this->correlationId   = $correlationId;
		$this->parentRequestId = $parentRequestId;
	}

	/**
	 * Wire-projected §6.5 `SyncJob` shape.
	 *
	 * @return array<string, mixed>
	 */
	public function job(): array {
		return $this->job;
	}

	/**
	 * Cross-request correlation identifier, or null when absent.
	 */
	public function correlationId(): ?string {
		return $this->correlationId;
	}

	/**
	 * Originating-request identifier, or null when absent.
	 */
	public function parentRequestId(): ?string {
		return $this->parentRequestId;
	}

	/**
	 * Render the §11.4 success envelope `data` shape: the
	 * wire-projected job map merged with two top-level correlation
	 * axes (`correlation_id`, `parent_request_id`). Both correlation
	 * axes are always present on the output map, taking the null
	 * value when absent on the originating record.
	 *
	 * @return array<string, mixed>
	 */
	public function toArray(): array {
		$out                      = $this->job;
		$out['correlation_id']    = $this->correlationId;
		$out['parent_request_id'] = $this->parentRequestId;
		return $out;
	}
}
