<?php
/**
 * Registry of pre-configured third-party service templates.
 *
 * @package BlaminhorEssentials
 */

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

/**
 * Loads every JSON file under `services/`, exposes them as PHP arrays, and
 * lets third-parties add their own via the `blaminhor_cookies_service_templates`
 * filter. Each template describes one service (handle, name, provider, default
 * category, regex script patterns for blocking, cookies declared, etc.).
 */
class Blaminhor_Essentials_Cookies_Service_Templates {

	/**
	 * @var string Absolute path of the services/ directory.
	 */
	protected $services_dir;

	/**
	 * @var array<string,array>|null Lazy-loaded cache.
	 */
	protected $cache = null;

	public function __construct( $services_dir ) {
		$this->services_dir = trailingslashit( $services_dir );
	}

	/**
	 * Get all registered services keyed by handle.
	 *
	 * @return array<string,array>
	 */
	public function all() {
		if ( null === $this->cache ) {
			$this->cache = $this->load_from_disk();
		}
		return (array) apply_filters( 'blaminhor_cookies_service_templates', $this->cache );
	}

	/**
	 * @param string $handle Service identifier.
	 * @return array|null
	 */
	public function get( $handle ) {
		$all = $this->all();
		return isset( $all[ $handle ] ) ? $all[ $handle ] : null;
	}

	/**
	 * Services grouped by category.
	 *
	 * @return array<string,array<string,array>>
	 */
	public function group_by_category() {
		$grouped = array();
		foreach ( $this->all() as $handle => $svc ) {
			$cat = $svc['category_default'] ?? 'marketing';
			if ( ! isset( $grouped[ $cat ] ) ) {
				$grouped[ $cat ] = array();
			}
			$grouped[ $cat ][ $handle ] = $svc;
		}
		return $grouped;
	}

	/**
	 * Scan the disk and return all valid JSON service files.
	 *
	 * @return array<string,array>
	 */
	protected function load_from_disk() {
		$out = array();
		if ( ! is_dir( $this->services_dir ) ) {
			return $out;
		}
		foreach ( glob( $this->services_dir . '*.json' ) as $file ) {
			$raw = file_get_contents( $file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
			if ( false === $raw ) {
				continue;
			}
			$data = json_decode( $raw, true );
			if ( ! is_array( $data ) || empty( $data['handle'] ) ) {
				continue;
			}
			$out[ $data['handle'] ] = $this->normalize( $data );
		}
		ksort( $out );
		return $out;
	}

	/**
	 * Provide sane defaults for every field.
	 *
	 * @param array $svc Raw service definition.
	 * @return array
	 */
	protected function normalize( array $svc ) {
		return array_merge(
			array(
				'handle'           => '',
				'name'             => '',
				'provider'         => '',
				'category_default' => 'marketing',
				'description'      => '',
				'privacy_url'      => '',
				'script_patterns'  => array(),
				'iframe_patterns'  => array(),
				'cookies'          => array(),
				'placeholder_type' => 'text',
				'gcm_signals'      => array(),
			),
			$svc
		);
	}
}
