<?php
/**
 * Speed in China — Self-Test REST Endpoints & WP-CLI Commands
 *
 * Provides diagnostic endpoints for testing all plugin mechanisms:
 * - API auth flow
 * - Features API connectivity
 * - Notifications API connectivity
 * - Globalping API connectivity
 * - HMAC-SHA256 signature verification
 *
 * @package SpeedInChina
 */

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

/**
 * Register self-test REST routes.
 */
add_action(
	'rest_api_init',
	function () {
		register_rest_route(
			'speed-in-china/v1',
			'/self-test',
			array(
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => 'speeinch_self_test_callback',
				'permission_callback' => function () {
					return current_user_can( 'manage_options' );
				},
			)
		);

		register_rest_route(
			'speed-in-china/v1',
			'/self-test/(?P<test>[a-z_-]+)',
			array(
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => 'speeinch_self_test_single_callback',
				'permission_callback' => function () {
					return current_user_can( 'manage_options' );
				},
				'args'                => array(
					'test' => array(
						'required'          => true,
						'sanitize_callback' => 'sanitize_text_field',
					),
				),
			)
		);
	}
);

/**
 * Run all self-tests.
 */
function speeinch_self_test_callback( $request ) {
	$results = array(
		'timestamp'  => current_time( 'mysql' ),
		'plugin_ver' => defined( 'SPEEINCH_PLUGIN_VERSION' ) ? SPEEINCH_PLUGIN_VERSION : 'unknown',
		'tests'      => array(),
	);

	$tests = array( 'constants', 'api_connectivity', 'features_api', 'notifications_api', 'hmac_auth', 'globalping', 'lottie_asset', 'google_fonts', 'resource_analysis' );
	foreach ( $tests as $test ) {
		$fn = "speeinch_test_{$test}";
		if ( function_exists( $fn ) ) {
			$results['tests'][ $test ] = call_user_func( $fn );
		}
	}

	$results['overall'] = 'pass';
	foreach ( $results['tests'] as $test ) {
		if ( $test['status'] === 'fail' ) {
			$results['overall'] = 'fail';
			break;
		}
	}

	return rest_ensure_response( $results );
}

/**
 * Run a single self-test.
 */
function speeinch_self_test_single_callback( $request ) {
	$test = $request->get_param( 'test' );
	$fn   = "speeinch_test_{$test}";

	if ( ! function_exists( $fn ) ) {
		return new WP_Error( 'invalid_test', "Unknown test: {$test}", array( 'status' => 404 ) );
	}

	return rest_ensure_response( call_user_func( $fn ) );
}

/* ========== Individual Tests ========== */

/**
 * Test: Plugin constants are defined correctly.
 */
function speeinch_test_constants() {
	$checks = array(
		'SPEEINCH_API_BASE_URL' => defined( 'SPEEINCH_API_BASE_URL' ) ? SPEEINCH_API_BASE_URL : null,
		'SPEEINCH_PLUGIN_URL'   => defined( 'SPEEINCH_PLUGIN_URL' ) ? SPEEINCH_PLUGIN_URL : null,
		'SPEEINCH_PLUGIN_PATH'  => defined( 'SPEEINCH_PLUGIN_PATH' ) ? SPEEINCH_PLUGIN_PATH : null,
	);

	$missing = array_filter(
		$checks,
		function ( $v ) {
			return $v === null;
		}
	);

	return array(
		'status'  => empty( $missing ) ? 'pass' : 'fail',
		'message' => empty( $missing )
			? 'All required constants defined.'
			: 'Missing constants: ' . implode( ', ', array_keys( $missing ) ),
		'values'  => $checks,
	);
}

/**
 * Test: API server connectivity (our intermediary API).
 */
function speeinch_test_api_connectivity() {
	if ( ! defined( 'SPEEINCH_API_BASE_URL' ) ) {
		return array(
			'status'  => 'fail',
			'message' => 'SPEEINCH_API_BASE_URL not defined.',
		);
	}

	$url      = esc_url( SPEEINCH_API_BASE_URL . '/wp-json/' );
	$response = wp_remote_get(
		$url,
		array(
			'timeout'   => 10,
			'sslverify' => false,
		)
	);

	if ( is_wp_error( $response ) ) {
		return array(
			'status'  => 'fail',
			'message' => 'API server unreachable: ' . $response->get_error_message(),
			'url'     => $url,
		);
	}

	$code = wp_remote_retrieve_response_code( $response );

	return array(
		'status'  => $code === 200 ? 'pass' : 'warn',
		'message' => "API server responded with HTTP {$code}.",
		'url'     => $url,
	);
}

/**
 * Test: Features API returns data for speed-test area.
 */
function speeinch_test_features_api() {
	if ( ! defined( 'SPEEINCH_API_BASE_URL' ) ) {
		return array(
			'status'  => 'fail',
			'message' => 'SPEEINCH_API_BASE_URL not defined.',
		);
	}

	$url      = esc_url( SPEEINCH_API_BASE_URL . '/wp-json/features-api/v1/area/speed-test' );
	$response = wp_remote_get(
		$url,
		array(
			'timeout'   => 10,
			'sslverify' => false,
		)
	);

	if ( is_wp_error( $response ) ) {
		return array(
			'status'  => 'fail',
			'message' => 'Features API unreachable: ' . $response->get_error_message(),
			'url'     => $url,
		);
	}

	$code = wp_remote_retrieve_response_code( $response );
	$body = json_decode( wp_remote_retrieve_body( $response ), true );

	$has_data = isset( $body['data']['features'] ) && is_array( $body['data']['features'] );

	return array(
		'status'         => ( $code === 200 && $has_data ) ? 'pass' : 'fail',
		'message'        => $code === 200
			? ( $has_data ? 'Features API returned ' . count( $body['data']['features'] ) . ' feature(s).' : 'Features API returned no features array.' )
			: "Features API responded with HTTP {$code}.",
		'url'            => $url,
		'features_count' => $has_data ? count( $body['data']['features'] ) : 0,
	);
}

/**
 * Test: Notifications API connectivity.
 */
function speeinch_test_notifications_api() {
	if ( ! defined( 'SPEEINCH_API_BASE_URL' ) ) {
		return array(
			'status'  => 'fail',
			'message' => 'SPEEINCH_API_BASE_URL not defined.',
		);
	}

	$url      = esc_url( SPEEINCH_API_BASE_URL . '/wp-json/notification-system-api/v1/notifications/latest' );
	$response = wp_remote_get(
		$url,
		array(
			'timeout'   => 10,
			'sslverify' => false,
		)
	);

	if ( is_wp_error( $response ) ) {
		return array(
			'status'  => 'warn',
			'message' => 'Notifications API unreachable: ' . $response->get_error_message(),
			'url'     => $url,
		);
	}

	$code = wp_remote_retrieve_response_code( $response );

	return array(
		'status'  => $code === 200 ? 'pass' : 'warn',
		'message' => "Notifications API responded with HTTP {$code}.",
		'url'     => $url,
	);
}

/**
 * Test: HMAC-SHA256 auth headers generate correctly.
 */
function speeinch_test_hmac_auth() {
	if ( ! function_exists( 'speeinch_get_auth_headers' ) ) {
		return array(
			'status'  => 'fail',
			'message' => 'speeinch_get_auth_headers() not found.',
		);
	}

	$headers = speeinch_get_auth_headers();
	$valid   = ! empty( $headers['X-SIC-Timestamp'] ) && ! empty( $headers['X-SIC-Signature'] );

	return array(
		'status'    => $valid ? 'pass' : 'fail',
		'message'   => $valid ? 'HMAC auth headers generated successfully.' : 'HMAC auth headers missing timestamp or signature.',
		'timestamp' => $headers['X-SIC-Timestamp'] ?? null,
		'sig_len'   => isset( $headers['X-SIC-Signature'] ) ? strlen( $headers['X-SIC-Signature'] ) : 0,
	);
}

/**
 * Test: Globalping API reachability.
 */
function speeinch_test_globalping() {
	$response = wp_remote_get(
		'https://api.globalping.io/v1/probes?limit=1',
		array(
			'headers' => array( 'Accept' => 'application/json' ),
			'timeout' => 15,
		)
	);

	if ( is_wp_error( $response ) ) {
		return array(
			'status'  => 'fail',
			'message' => 'Cannot reach api.globalping.io: ' . $response->get_error_message(),
		);
	}

	$code = wp_remote_retrieve_response_code( $response );

	return array(
		'status'  => $code === 200 ? 'pass' : 'warn',
		'message' => "Globalping API responded with HTTP {$code}.",
	);
}

/**
 * Test: Lottie animation JSON asset exists.
 */
function speeinch_test_lottie_asset() {
	$path   = SPEEINCH_PLUGIN_PATH . 'assets/js/vendor/dotlottie/Speedometer.json';
	$exists = file_exists( $path );
	$size   = $exists ? filesize( $path ) : 0;

	return array(
		'status'  => ( $exists && $size > 100 ) ? 'pass' : 'fail',
		'message' => $exists
			? "Lottie animation file exists ({$size} bytes)."
			: 'Lottie animation file missing at assets/js/vendor/dotlottie/Speedometer.json.',
		'path'    => $path,
	);
}

/**
 * Test: Google Fonts detection module loaded.
 */
function speeinch_test_google_fonts() {
	if ( ! class_exists( 'SPEEINCH_Google_Fonts' ) ) {
		return array(
			'status'  => 'fail',
			'message' => 'SPEEINCH_Google_Fonts class not loaded.',
		);
	}

	$enabled = get_option( SPEEINCH_Google_Fonts::OPTION_ENABLED, false );

	return array(
		'status'  => 'pass',
		'message' => 'Google Fonts module loaded. Localization ' . ( $enabled ? 'ENABLED' : 'disabled' ) . '.',
		'enabled' => (bool) $enabled,
	);
}

/**
 * Test: Resource Analysis module loaded and can run.
 */
function speeinch_test_resource_analysis() {
	if ( ! class_exists( 'SPEEINCH_Resource_Analysis' ) ) {
		return array(
			'status'  => 'fail',
			'message' => 'SPEEINCH_Resource_Analysis class not loaded.',
		);
	}

	$results = SPEEINCH_Resource_Analysis::analyze();

	return array(
		'status'  => 'pass',
		'message' => sprintf(
			'Resource analysis ran. Score: %d/100. Found %d critical, %d warnings, %d info.',
			$results['summary']['score'],
			$results['summary']['critical'],
			$results['summary']['warnings'],
			$results['summary']['info']
		),
		'summary' => $results['summary'],
	);
}
