<?php

/**
 * Playground-first gate before installing built plugins on the live site.
 *
 * @package LolaCore\PluginBuilder\Gate
 * @license GPL-2.0-or-later
 */

declare(strict_types=1);

namespace LolaCore\PluginBuilder\Gate;

use LolaCore\Builder\Gate\AttestationGate;
use LolaCore\PluginBuilder\Artifact\PluginArtifactAdapter;
use LolaCore\PluginBuilder\Generation\RuntimeValidator;

if (! defined('ABSPATH')) {
	exit;
}

/**
 * Static façade over the shared AttestationGate, configured for the Plugin
 * Builder library (FS-S1 backbone extraction).
 *
 * Keeps the public surface every Plugin Builder call-site and shipped library
 * relies on: same methods, same statuses, same '_lc_pb_pg_*' meta keys, and
 * the same 'lc_pb_loadsafe_{id}_{v}' transients (now derived inside the gate
 * from the adapter's meta prefix).
 */
final class PlaygroundGate {

	public const STATUS_UNTESTED = AttestationGate::STATUS_UNTESTED;
	public const STATUS_OPENED   = AttestationGate::STATUS_OPENED;
	public const STATUS_ATTESTED = AttestationGate::STATUS_ATTESTED;
	public const STATUS_FAILED   = AttestationGate::STATUS_FAILED;

	public const META_STATUS           = '_lc_pb_pg_gate_status';
	public const META_ATTESTED_VERSION = '_lc_pb_pg_attested_version';
	public const META_ATTESTED_AT      = '_lc_pb_pg_attested_at';
	public const META_OPENED_AT        = '_lc_pb_pg_opened_at';

	private static ?AttestationGate $gate = null;

	private static function gate(): AttestationGate {
		if (self::$gate === null) {
			self::$gate = new AttestationGate(new PluginArtifactAdapter());
		}

		return self::$gate;
	}

	/**
	 * Reset gate when a new library version is saved (create or update).
	 */
	public static function reset( int $post_id ): void {
		self::gate()->reset($post_id);
	}

	/**
	 * Record that the user opened Playground (flow checkpoint, not technical verification).
	 */
	public static function markOpened( int $post_id ): void {
		self::gate()->markOpened($post_id);
	}

	/**
	 * User confirmed Playground testing succeeded for the current version.
	 */
	public static function markAttested( int $post_id ): void {
		self::gate()->markAttested($post_id);
	}

	/**
	 * User reported issues during Playground testing.
	 */
	public static function markFailed( int $post_id ): void {
		self::gate()->markFailed($post_id);
	}

	public static function getStatus( int $post_id ): string {
		return self::gate()->getStatus($post_id);
	}

	public static function getAttestedVersion( int $post_id ): int {
		return self::gate()->getAttestedVersion($post_id);
	}

	public static function isInstallAllowed( int $post_id ): bool {
		return self::gate()->isInstallAllowed($post_id);
	}

	/**
	 * @throws \Exception When install is blocked by the Playground gate.
	 */
	public static function assertInstallAllowed( int $post_id ): void {
		self::gate()->assertInstallAllowed($post_id);
	}

	/**
	 * Load-time fatal check before offering Playground or installing locally.
	 *
	 * @throws \Exception When generated PHP fatals on load.
	 */
	public static function assertLoadSafe( int $post_id, ?RuntimeValidator $validator = null ): void {
		self::gate()->assertLoadSafe($post_id, $validator);
	}

	/**
	 * Seed load-safe cache from build-time validation (CodeReviewer) so Playground AJAX
	 * does not repeat the same RuntimeValidator loopback scrape.
	 *
	 * @param array{status?: string, message?: string, line?: int} $runtime_result
	 */
	public static function seedLoadSafeCache( int $post_id, int $version, string $php, array $runtime_result ): void {
		self::gate()->seedLoadSafeCache($post_id, $version, $php, $runtime_result);
	}

	/**
	 * Gate flags exposed to chat artifacts and admin UI.
	 *
	 * @return array{gate_status: string, install_allowed: bool, attested_version: int, current_version: int}
	 */
	public static function uiFlags( int $post_id ): array {
		return self::gate()->uiFlags($post_id);
	}
}
