<?php
/**
 * Plugin Name: ArkHost Security Pack
 * Description: A free, lightweight security plugin with zero upsells. Login protection, IP blocking, hardening, and activity logging.
 * Version: 1.1
 * Requires at least: 5.0
 * Requires PHP: 7.4
 * Author: ArkHost
 * Author URI: https://arkhost.com
 * License: GPL v2 or later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain: arkhost-security-pack
 * Domain Path: /languages
 *
 * @package ArkHost_Security_Pack
 */

// Prevent direct access.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

// Plugin constants.
define( 'ARKSP_VERSION', '1.1' );
define( 'ARKSP_PLUGIN_FILE', __FILE__ );
define( 'ARKSP_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'ARKSP_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
define( 'ARKSP_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );

/**
 * Main plugin class.
 */
final class ARKSP_Plugin {

	/**
	 * Single instance.
	 *
	 * @var ARKSP_Plugin
	 */
	private static $instance = null;

	/**
	 * Plugin components.
	 *
	 * @var array
	 */
	private $components = array();

	/**
	 * Get single instance.
	 *
	 * @return ARKSP_Plugin
	 */
	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Constructor.
	 */
	private function __construct() {
		$this->load_dependencies();
		$this->init_hooks();
	}

	/**
	 * Load required files.
	 */
	private function load_dependencies() {
		require_once ARKSP_PLUGIN_DIR . 'includes/class-arksp-helper.php';
		require_once ARKSP_PLUGIN_DIR . 'includes/class-arksp-db.php';
		require_once ARKSP_PLUGIN_DIR . 'includes/class-arksp-activity-log.php';
		require_once ARKSP_PLUGIN_DIR . 'includes/class-arksp-ip-control.php';
		require_once ARKSP_PLUGIN_DIR . 'includes/class-arksp-login-protection.php';
		require_once ARKSP_PLUGIN_DIR . 'includes/class-arksp-hardening.php';
		require_once ARKSP_PLUGIN_DIR . 'includes/class-arksp-geo-blocking.php';
		require_once ARKSP_PLUGIN_DIR . 'includes/class-arksp-two-factor.php';
		require_once ARKSP_PLUGIN_DIR . 'includes/class-arksp-file-integrity.php';
		require_once ARKSP_PLUGIN_DIR . 'includes/class-arksp-malware-scanner.php';

		if ( is_admin() ) {
			require_once ARKSP_PLUGIN_DIR . 'includes/class-arksp-admin.php';
		}
	}

	/**
	 * Initialize hooks.
	 */
	private function init_hooks() {
		register_activation_hook( ARKSP_PLUGIN_FILE, array( 'ARKSP_DB', 'activate' ) );
		register_deactivation_hook( ARKSP_PLUGIN_FILE, array( 'ARKSP_DB', 'deactivate' ) );

		add_action( 'plugins_loaded', array( 'ARKSP_DB', 'maybe_upgrade' ) );
		add_action( 'init', array( $this, 'init_components' ), 1 );

		// Schedule cleanup cron.
		add_action( 'arksp_daily_cleanup', array( 'ARKSP_Activity_Log', 'cleanup_old_logs' ) );

		if ( ! wp_next_scheduled( 'arksp_daily_cleanup' ) ) {
			wp_schedule_event( time(), 'daily', 'arksp_daily_cleanup' );
		}
	}

	/**
	 * Initialize plugin components.
	 *
	 * Note: Order matters! Components that may exit early (like login_protection
	 * with custom login URLs) must be initialized AFTER components that need
	 * to register hooks (like two_factor for 2FA on login).
	 */
	public function init_components() {
		$this->components['activity_log']     = new ARKSP_Activity_Log();
		$this->components['ip_control']       = new ARKSP_IP_Control();
		$this->components['hardening']        = new ARKSP_Hardening();
		$this->components['geo_blocking']     = new ARKSP_Geo_Blocking();
		$this->components['two_factor']       = new ARKSP_Two_Factor();
		$this->components['file_integrity']   = new ARKSP_File_Integrity();
		$this->components['malware_scanner']  = new ARKSP_Malware_Scanner();

		// Login protection must be last - custom login URL handling may exit early.
		$this->components['login_protection'] = new ARKSP_Login_Protection();

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

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

	/**
	 * Get default settings.
	 *
	 * @return array
	 */
	public static function get_default_settings() {
		return array(
			// Login Protection.
			'login_limit_enabled'      => true,
			'login_max_attempts'       => 5,
			'login_lockout_duration'   => 15,
			'login_rename_enabled'     => false,
			'login_custom_url'         => '',
			'hide_wp_admin'            => false,
			'honeypot_enabled'         => true,
			'honeypot_ban_duration'    => 60, // Minutes.
			'hide_login_errors'        => true,
			'admin_login_notify'       => false,

			// Login Access Restriction.
			'admin_access_restriction' => false,
			'admin_allowed_countries'  => array(),
			'admin_allowed_ips'        => '',

			// IP Control.
			'ip_whitelist'             => '',
			'ip_blacklist'             => '',
			'auto_blacklist_enabled'   => false,
			'auto_blacklist_threshold' => 3,

			// Geo Blocking.
			'geo_blocking_enabled'     => false,
			'geo_blocked_countries'    => array(),
			'geo_database_path'        => '',

			// Hardening.
			'disable_xmlrpc'               => true,
			'disable_file_editing'         => true,
			'disable_application_passwords' => false,
			'restrict_rest_api'            => true,
			'remove_wp_version'            => true,
			'remove_feed_links'            => false,
			'add_security_headers'         => true,
			'disable_user_enumeration'     => true,
			'disable_pingbacks'            => true,

			// Two-Factor Authentication.
			'two_factor_enabled'       => false,
			'two_factor_enforce_admin' => false,

			// File Integrity.
			'file_integrity_enabled'   => true,

			// Malware Scanner.
			'malware_scan_enabled'     => true,

			// Email Alerts.
			'email_alerts_enabled'     => false,
			'email_alerts_address'     => '',
			'email_alert_threshold'    => 3,

			// Activity Log.
			'log_retention_days'       => 30,
		);
	}

	/**
	 * Get a setting value.
	 *
	 * @param string $key     Setting key.
	 * @param mixed  $default Default value.
	 * @return mixed
	 */
	public static function get_setting( $key, $default = null ) {
		$settings = get_option( 'arksp_settings', array() );
		$defaults = self::get_default_settings();

		if ( isset( $settings[ $key ] ) ) {
			return $settings[ $key ];
		}

		if ( null !== $default ) {
			return $default;
		}

		return isset( $defaults[ $key ] ) ? $defaults[ $key ] : null;
	}

	/**
	 * Update a setting value.
	 *
	 * @param string $key   Setting key.
	 * @param mixed  $value Setting value.
	 * @return bool
	 */
	public static function update_setting( $key, $value ) {
		$settings         = get_option( 'arksp_settings', array() );
		$settings[ $key ] = $value;
		return update_option( 'arksp_settings', $settings );
	}

	/**
	 * Prevent cloning.
	 */
	private function __clone() {}

	/**
	 * Prevent unserialization.
	 */
	public function __wakeup() {
		throw new Exception( 'Cannot unserialize singleton' );
	}
}

/**
 * Get plugin instance.
 *
 * @return ARKSP_Plugin
 */
function arksp() {
	return ARKSP_Plugin::instance();
}

// Initialize plugin.
arksp();
