<?php
/**
 * `wp blaminhor https-redirect ...` — HTTPS Redirect module commands.
 *
 * @package BlaminhorEssentials
 */

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

if ( ! defined( 'WP_CLI' ) || ! WP_CLI ) {
	return;
}

/**
 * Toggle and configure forced HTTPS + HSTS from the command line.
 */
class Blaminhor_Essentials_CLI_HTTPS_Redirect extends Blaminhor_Essentials_CLI_Module {

	/**
	 * @var string
	 */
	protected $module_id = 'https-redirect';

	/**
	 * Show the current HTTPS Redirect settings.
	 *
	 * ## OPTIONS
	 *
	 * [--format=<format>]
	 * : Render format (table, json, csv, yaml). Default: table.
	 *
	 * ## EXAMPLES
	 *
	 *     $ wp blaminhor https-redirect get
	 *
	 * @when after_wp_load
	 *
	 * @param array $args       Positional args (unused).
	 * @param array $assoc_args Associative args.
	 */
	public function get( $args, $assoc_args ) {
		$module   = $this->get_module_instance();
		$settings = $module->get_effective_settings();

		$rows = array(
			array( 'key' => 'enabled',           'value' => $settings['enabled'] ? 'true' : 'false' ),
			array( 'key' => 'redirect_admin',    'value' => $settings['redirect_admin'] ? 'true' : 'false' ),
			array( 'key' => 'fix_mixed_content', 'value' => $settings['fix_mixed_content'] ? 'true' : 'false' ),
			array( 'key' => 'hsts_enabled',      'value' => $settings['hsts_enabled'] ? 'true' : 'false' ),
			array( 'key' => 'hsts_max_age',      'value' => (string) (int) $settings['hsts_max_age'] ),
		);

		$this->format_for_output( $rows, $assoc_args, array( 'key', 'value' ) );
	}

	/**
	 * Print whether forced HTTPS is currently enabled (porcelain output).
	 *
	 * Exits 0 if enabled, 1 otherwise.
	 *
	 * @when after_wp_load
	 *
	 * @param array $args       Positional args (unused).
	 * @param array $assoc_args Associative args (unused).
	 */
	public function status( $args, $assoc_args ) {
		$module = $this->get_module_instance();
		if ( $module->get_setting( 'enabled' ) ) {
			WP_CLI::line( 'enabled' );
			return;
		}
		WP_CLI::line( 'disabled' );
		WP_CLI::halt( 1 );
	}

	/**
	 * Enable forced HTTPS (optionally update related flags atomically).
	 *
	 * ## OPTIONS
	 *
	 * [--redirect-admin=<bool>]
	 * : Redirect wp-admin and login pages too. Default: keep current.
	 *
	 * [--fix-mixed-content=<bool>]
	 * : Rewrite http:// URLs in the output to https:// at runtime.
	 *
	 * [--hsts=<bool>]
	 * : Enable the Strict-Transport-Security header.
	 *
	 * [--hsts-max-age=<seconds>]
	 * : HSTS max-age value (default 31536000 = 1 year).
	 *
	 * ## EXAMPLES
	 *
	 *     $ wp blaminhor https-redirect enable
	 *     $ wp blaminhor https-redirect enable --hsts=true --hsts-max-age=63072000
	 *
	 * @when after_wp_load
	 *
	 * @param array $args       Positional args (unused).
	 * @param array $assoc_args Associative args.
	 */
	public function enable( $args, $assoc_args ) {
		$this->ensure_capabilities();
		$assoc_args['enabled'] = '1';
		$this->apply( $assoc_args, __( 'HTTPS redirect enabled.', 'blaminhor-essentials' ), 'https_enable' );
	}

	/**
	 * Disable forced HTTPS (other flags preserved).
	 *
	 * ## OPTIONS
	 *
	 * [--yes]
	 * : Skip the interactive confirmation prompt.
	 *
	 * ## EXAMPLES
	 *
	 *     $ wp blaminhor https-redirect disable --yes
	 *
	 * @when after_wp_load
	 *
	 * @param array $args       Positional args (unused).
	 * @param array $assoc_args Associative args.
	 */
	public function disable( $args, $assoc_args ) {
		$this->ensure_capabilities();
		$module = $this->get_module_instance();

		if ( ! $module->get_setting( 'enabled' ) ) {
			WP_CLI::warning( __( 'HTTPS redirect is already disabled.', 'blaminhor-essentials' ) );
			return;
		}

		WP_CLI::confirm(
			__( 'Disable forced HTTPS redirect? Visitors will no longer be sent to https:// automatically.', 'blaminhor-essentials' ),
			$assoc_args
		);

		$assoc_args['__no_enabled__'] = true;
		$this->apply( $assoc_args, __( 'HTTPS redirect disabled.', 'blaminhor-essentials' ), 'https_disable' );
	}

	/**
	 * Update HTTPS Redirect settings without toggling on/off.
	 *
	 * ## OPTIONS
	 *
	 * [--redirect-admin=<bool>]
	 * : Redirect wp-admin and login pages.
	 *
	 * [--fix-mixed-content=<bool>]
	 * : Rewrite http:// URLs in the output to https:// at runtime.
	 *
	 * [--hsts=<bool>]
	 * : Enable the Strict-Transport-Security header.
	 *
	 * [--hsts-max-age=<seconds>]
	 * : HSTS max-age value.
	 *
	 * ## EXAMPLES
	 *
	 *     $ wp blaminhor https-redirect set --redirect-admin=true --hsts=true
	 *
	 * @when after_wp_load
	 *
	 * @param array $args       Positional args (unused).
	 * @param array $assoc_args Associative args.
	 */
	public function set( $args, $assoc_args ) {
		$this->ensure_capabilities();
		$this->apply( $assoc_args, __( 'HTTPS Redirect settings updated.', 'blaminhor-essentials' ), 'https_set' );
	}

	/**
	 * Build the $data payload for process_settings() while preserving
	 * every flag that wasn't explicitly overridden via the CLI.
	 *
	 * @param array  $assoc_args CLI args. `__no_enabled__` (special) instructs
	 *                           the builder to omit the `enabled` key.
	 * @param string $success    Localised success message.
	 * @param string $event      Logger event slug.
	 */
	private function apply( $assoc_args, $success, $event ) {
		$module  = $this->get_module_instance();
		$current = $module->get_effective_settings();

		$data = array(
			'hsts_max_age' => isset( $assoc_args['hsts-max-age'] ) ? (string) (int) $assoc_args['hsts-max-age'] : (string) (int) $current['hsts_max_age'],
		);

		$bool_map = array(
			'redirect-admin'    => 'redirect_admin',
			'fix-mixed-content' => 'fix_mixed_content',
			'hsts'              => 'hsts_enabled',
		);

		foreach ( $bool_map as $cli_flag => $setting_key ) {
			if ( array_key_exists( $cli_flag, $assoc_args ) ) {
				if ( $this->parse_bool( $assoc_args[ $cli_flag ] ) ) {
					$data[ $setting_key ] = '1';
				}
			} elseif ( ! empty( $current[ $setting_key ] ) ) {
				$data[ $setting_key ] = '1';
			}
		}

		if ( empty( $assoc_args['__no_enabled__'] ) ) {
			if ( isset( $assoc_args['enabled'] ) ) {
				if ( $this->parse_bool( $assoc_args['enabled'] ) ) {
					$data['enabled'] = '1';
				}
			} elseif ( ! empty( $current['enabled'] ) ) {
				$data['enabled'] = '1';
			}
		}

		$result = $module->apply_settings( $data );
		if ( is_wp_error( $result ) ) {
			WP_CLI::error( $result->get_error_message() );
		}

		blaminhor_essentials_log(
			sprintf( 'HTTPS Redirect updated via WP-CLI (event=%s).', $event ),
			'info',
			'cli',
			array( 'event' => $event )
		);
		WP_CLI::success( $success );
	}
}
