<?php
/**
 * Recording workspace adapter contract.
 *
 * @package ScheduledChanges
 */

namespace ScheduledChanges\Recording;

use ScheduledChanges\Domain\Recording\RecordingSession;
use ScheduledChanges\Domain\Shared\Uuid;

/**
 * Provider-owned lifecycle for isolated Record Changes workspaces.
 *
 * @phpstan-type RecordingContext array{
 *   session_uuid: non-empty-string,
 *   source_provider_id: non-empty-string,
 *   source_type: non-empty-string,
 *   source_reference: non-empty-string,
 *   source_id: int,
 *   workspace_provider_id?: non-empty-string|null,
 *   workspace_type?: non-empty-string|null,
 *   workspace_reference?: non-empty-string|null,
 *   workspace_id?: int|null,
 *   owner_id: int,
 *   phase: non-empty-string,
 *   ...
 * }
 * @phpstan-type RecordingSnapshot array{
 *   captured_at_utc?: string,
 *   objects?: array<int,array<string,mixed>>,
 *   ...
 * }
 * @phpstan-type RecordingDiff array{
 *   captured_at_utc?: string,
 *   changes: array<int,array<string,mixed>>,
 *   warnings: array<int,array<string,mixed>>,
 *   selected_change_ids: array<int,string>,
 *   diagnostics?: array<string,mixed>,
 *   ...
 * }
 * @phpstan-type RecordingRelationMap array<string,mixed>
 * @phpstan-type RecordingProviderMap array<string,mixed>
 */
interface RecordingWorkspaceAdapter {
	public function sourceType(): string;

	public function workspaceType(): string;

	public function assertCanStart( int $source_id ): void;

	public function assertCanUse( RecordingSession $session ): void;

	/**
	 * Captures the immutable baseline for the source object.
	 *
	 * @return array<string,mixed>
	 * @phpstan-return RecordingSnapshot
	 */
	public function captureSourceBaseline( int $source_id ): array;

	public function create( RecordingWorkspaceRequest $request ): RecordingWorkspaceResult;

	/**
	 * Captures the current editable workspace state.
	 *
	 * @return array<string,mixed>
	 * @phpstan-return RecordingSnapshot
	 */
	public function captureWorkspace( RecordingSession $session ): array;

	/**
	 * Captures the live source for source-mutation detection.
	 *
	 * @return array<string,mixed>
	 * @phpstan-return RecordingSnapshot
	 */
	public function captureSource( RecordingSession $session ): array;

	/**
	 * Builds a structured diff from the latest workspace capture.
	 *
	 * @param array<string,mixed> $workspace_snapshot Latest workspace snapshot.
	 * @return array<string,mixed>
	 * @phpstan-param RecordingSnapshot $workspace_snapshot
	 * @phpstan-return RecordingDiff
	 */
	public function buildDiff( RecordingSession $session, array $workspace_snapshot ): array;

	public function cleanup( RecordingSession $session, string $reason ): void;

	public function cleanupCreated( RecordingWorkspaceRequest $request, RecordingWorkspaceResult $workspace, string $reason ): void;

	public function lockTarget( int $source_id ): string;

	public function defaultLaunchName( RecordingSession $session ): string;

	/**
	 * @return array<string,mixed>
	 * @phpstan-return RecordingContext
	 */
	public function context( Uuid $uuid, int $source_id, ?int $workspace_id, int $owner_id, string $phase ): array;
}
