<?php
/**
 * Launch execution hook payload.
 *
 * @package ScheduledChanges
 */

namespace ScheduledChanges\Extension;

/**
 * Typed payload emitted before and after launch execution.
 */
final class LaunchExecutionHookPayload {
	private int $run_id;
	private ?string $run_uuid;
	private int $launch_id;
	private int $launch_version_id;
	private ?string $status;

	private function __construct(
		int $run_id,
		?string $run_uuid,
		int $launch_id,
		int $launch_version_id,
		?string $status
	) {
		if ( $run_id <= 0 || $launch_id <= 0 || $launch_version_id <= 0 ) {
			throw new \InvalidArgumentException( 'Launch execution hook identifiers must be positive.' );
		}

		if ( null !== $run_uuid && '' === trim( $run_uuid ) ) {
			throw new \InvalidArgumentException( 'Launch execution hook run UUID cannot be empty.' );
		}

		if ( null !== $status && '' === trim( $status ) ) {
			throw new \InvalidArgumentException( 'Launch execution hook status cannot be empty.' );
		}

		$this->run_id            = $run_id;
		$this->run_uuid          = $run_uuid;
		$this->launch_id         = $launch_id;
		$this->launch_version_id = $launch_version_id;
		$this->status            = $status;
	}

	/**
	 * Creates the before-execution hook payload.
	 */
	public static function before( int $run_id, string $run_uuid, int $launch_id, int $launch_version_id ): self {
		return new self( $run_id, $run_uuid, $launch_id, $launch_version_id, null );
	}

	/**
	 * Creates the after-execution hook payload.
	 */
	public static function after( int $run_id, int $launch_id, int $launch_version_id, string $status ): self {
		return new self( $run_id, null, $launch_id, $launch_version_id, $status );
	}

	/**
	 * Returns the public WordPress hook payload.
	 *
	 * @return array{run_id:int,run_uuid?:string,launch_id:int,launch_version_id:int,status?:string}
	 */
	public function toArray(): array {
		$payload = array(
			'run_id'            => $this->run_id,
			'launch_id'         => $this->launch_id,
			'launch_version_id' => $this->launch_version_id,
		);

		if ( null !== $this->run_uuid ) {
			$payload['run_uuid'] = $this->run_uuid;
		}

		if ( null !== $this->status ) {
			$payload['status'] = $this->status;
		}

		return $payload;
	}
}
