<?php
/**
 * Main plugin singleton: wires all components.
 *
 * @package Upgrade_Pilot
 */

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

/**
 * Class UPilot_Plugin
 */
final class UPilot_Plugin {

	/**
	 * Singleton instance.
	 *
	 * @var UPilot_Plugin|null
	 */
	private static $instance = null;

	/**
	 * Component instances, keyed by short name.
	 *
	 * @var array<string,object>
	 */
	private $components = array();

	/**
	 * Get the singleton.
	 *
	 * @return UPilot_Plugin
	 */
	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
			self::$instance->boot();
		}
		return self::$instance;
	}

	/**
	 * Access a component.
	 *
	 * @param string $key Component key.
	 * @return object|null
	 */
	public function get( $key ) {
		return isset( $this->components[ $key ] ) ? $this->components[ $key ] : null;
	}

	/**
	 * Boot all components.
	 */
	private function boot() {
		UPilot_Install::maybe_upgrade();

		$this->components['wporg']      = new UPilot_WPOrg_Client();
		$this->components['identity']   = new UPilot_Identity( $this->components['wporg'] );
		$this->components['server']     = new UPilot_Server_Check();
		$this->components['metadata']   = new UPilot_Metadata_Check( $this->components['identity'] );
		$this->components['ruleset']    = new UPilot_Ruleset();
		$this->components['scanner']    = new UPilot_Scanner( $this->components['ruleset'] );
		$this->components['verdict']    = new UPilot_Verdict( $this->components['server'], $this->components['metadata'], $this->components['scanner'] );
		$this->components['compromise'] = new UPilot_Compromise_List();
		$this->components['snapshot']   = new UPilot_Snapshot( $this->components['identity'], $this->components['wporg'], $this->components['compromise'] );
		$this->components['alerts']     = new UPilot_Alerts();
		$this->components['freeze']     = new UPilot_Freeze( $this->components['compromise'] );
		$this->components['report']     = new UPilot_Report( $this->components['verdict'], $this->components['snapshot'] );
		$this->components['sitehealth'] = new UPilot_Site_Health( $this->components['report'] );
		$this->components['cron']       = new UPilot_Cron( $this->components['scanner'], $this->components['snapshot'], $this->components['alerts'] );
		$this->components['rest']       = new UPilot_REST( $this );

		if ( is_admin() ) {
			$this->components['admin'] = new UPilot_Admin( $this );
		}

		if ( defined( 'WP_CLI' ) && WP_CLI ) {
			UPilot_CLI::register( $this );
		}

		/**
		 * Fires when Upgrade Pilot has finished booting. The Pro add-on attaches here.
		 *
		 * @param UPilot_Plugin $plugin Plugin instance.
		 */
		do_action( 'upilot_loaded', $this );
	}

	/**
	 * Private constructor: use instance().
	 */
	private function __construct() {}
}
