<?php

/**
 * Plugin Builder adapter for the shared builder backbone.
 *
 * @package LolaCore\PluginBuilder\Artifact
 * @license GPL-2.0-or-later
 */

declare(strict_types=1);

namespace LolaCore\PluginBuilder\Artifact;

// phpcs:disable WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Diagnostic exception messages; escaped at REST/chat presentation layer.

use LolaCore\Builder\Artifact\ArtifactAdapter;
use LolaCore\Builder\Artifact\FilesMap;
use LolaCore\PluginBuilder\Packaging\PluginFileNormalizer;
use LolaCore\PluginBuilder\PostType\PluginPostType;

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

/**
 * Maps the lolacore_plugin library CPT onto the backbone's artifact contract.
 *
 * The '_lc_pb_' prefix reproduces the shipped gate meta keys and load-safe
 * transients byte for byte — live user libraries depend on them.
 */
final class PluginArtifactAdapter implements ArtifactAdapter {

	public function postType(): string {
		return PluginPostType::POST_TYPE;
	}

	public function metaPrefix(): string {
		return '_lc_pb_';
	}

	public function currentVersion( int $postId ): int {
		return max(1, (int) get_post_meta($postId, PluginPostType::META_VERSION, true));
	}

	public function slug( int $postId ): string {
		return (string) get_post_meta($postId, PluginPostType::META_SLUG, true);
	}

	/**
	 * @return array<int, mixed>
	 */
	public function dependencies( int $postId ): array {
		$dependencies = get_post_meta($postId, PluginPostType::META_DEPENDENCIES, true);

		return is_array($dependencies) ? $dependencies : array();
	}

	/**
	 * Disk-bound tree mirroring LocalInstaller::install: normalized main PHP
	 * plus the js/css blobs exactly as stored (empty blobs included — the
	 * installer has always written them as empty files).
	 */
	public function filesMap( int $postId ): FilesMap {
		$slug = sanitize_title($this->slug($postId));
		if ($slug === '') {
			throw new \Exception(__('Built plugin slug is missing.', 'lolacore'));
		}

		return FilesMap::fromArray(array(
			$slug . '.php' => $this->runtimePhp($postId),
			$slug . '.js'  => (string) get_post_meta($postId, PluginPostType::META_JS, true),
			$slug . '.css' => (string) get_post_meta($postId, PluginPostType::META_CSS, true),
		));
	}

	public function storedPhp( int $postId ): string {
		return (string) get_post_meta($postId, PluginPostType::META_PHP, true);
	}

	/**
	 * Main PHP as it loads from disk: the deterministic normalizers applied at
	 * every write-to-disk boundary. Without a slug the blob passes through raw
	 * (mirrors the shipped gate behavior).
	 */
	public function runtimePhp( int $postId ): string {
		$php  = $this->storedPhp($postId);
		$slug = $this->slug($postId);

		if ($slug === '') {
			return $php;
		}

		return PluginFileNormalizer::normalizePhp($php, $slug, $this->currentVersion($postId));
	}
}

