<?php
/**
 * WordPress installed-plugin inventory.
 *
 * @package LocalGuardScanner
 */

namespace LocalGuardScanner\Infrastructure\WordPress;

use RuntimeException;

/**
 * Reads plugin versions and activation state locally across a network.
 */
final class InstalledPluginInventory {
	/**
	 * @param int[] $site_ids Included site IDs.
	 * @return array{installed:array<string,array<string,mixed>>,active:array<string,bool>}
	 */
	public function collect( array $site_ids ) {
		if ( ! function_exists( 'get_plugins' ) ) {
			$plugin_api = ABSPATH . 'wp-admin/includes/plugin.php';
			if ( ! is_readable( $plugin_api ) ) {
				throw new RuntimeException( 'WordPress plugin inventory API is unavailable.' );
			}
			require_once $plugin_api;
		}
		$installed         = get_plugins();
		$network           = is_multisite() ? get_site_option( 'active_sitewide_plugins', array() ) : array();
		$site_plugin_lists = array();
		foreach ( $site_ids as $site_id ) {
			$site_plugins        = is_multisite() ? get_blog_option( (int) $site_id, 'active_plugins', array() ) : get_option( 'active_plugins', array() );
			$site_plugin_lists[] = is_array( $site_plugins ) ? $site_plugins : array();
		}
		return array(
			'installed' => $installed,
			'active'    => self::aggregate_active( is_array( $network ) ? $network : array(), $site_plugin_lists ),
		);
	}

	/**
	 * Aggregate network and per-site activation without exposing site membership.
	 *
	 * @param array<array-key,mixed> $network_plugins Network active plugin map.
	 * @param array<int,mixed>       $site_plugin_lists Per-site active plugin lists.
	 * @return array<string,bool>
	 */
	public static function aggregate_active( array $network_plugins, array $site_plugin_lists ) {
		$active = array();
		foreach ( array_keys( $network_plugins ) as $plugin_file ) {
			if ( is_string( $plugin_file ) ) {
				$active[ $plugin_file ] = true;
			}
		}
		foreach ( $site_plugin_lists as $site_plugins ) {
			if ( ! is_array( $site_plugins ) ) {
				continue;
			}
			foreach ( $site_plugins as $plugin_file ) {
				if ( is_string( $plugin_file ) ) {
					$active[ $plugin_file ] = true;
				}
			}
		}
		return $active;
	}
}
