<?php

class WPML_Debug_Information {

	/** @var wpdb $wpdb */
	public $wpdb;

	/** @var SitePress $sitepress */
	protected $sitepress;

	protected $info;

	/**
	 * @param wpdb      $wpdb
	 * @param SitePress $sitepress
	 */
	public function __construct( $wpdb, $sitepress ) {
		$this->wpdb      = $wpdb;
		$this->sitepress = $sitepress;
		$this->info  = new WPML_Support_Info( $this->wpdb );
	}

	public function run() {
		$info = array( 'core', 'plugins', 'theme', 'extra-debug' );

		$output = array();
		foreach ( $info as $type ) {
			switch ( $type ) {
				case 'core':
					$output['core'] = $this->get_core_info();
					break;
				case 'plugins':
					$output['plugins'] = $this->get_plugins_info();
					break;
				case 'theme':
					$output['theme'] = $this->get_theme_info();
					break;
				case 'extra-debug':
					$output['extra-debug'] = apply_filters( 'icl_get_extra_debug_info', array() );
					break;
			}
		}

		return $output;
	}

	function get_core_info() {

		$core = array(
			'Wordpress' => array(
				'Multisite'          => is_multisite() ? 'Yes' : 'No',
				'SiteURL'            => site_url(),
				'HomeURL'            => home_url(),
				'Version'            => get_bloginfo( 'version' ),
				'PermalinkStructure' => get_option( 'permalink_structure' ),
				'PostTypes'          => implode( ', ', get_post_types( '', 'names' ) ),
				'PostStatus'         => implode( ', ', get_post_stati() ),
				'RestEnabled'        => wpml_is_rest_enabled(false) ? 'Yes' : 'No',
			),
			'Server'    => array(
				'jQueryVersion'  => wp_script_is( 'jquery', 'registered' ) ? $GLOBALS['wp_scripts']->registered['jquery']->ver : __( 'n/a', 'bbpress' ),
				'PHPVersion'     => $this->sitepress->get_wp_api()->phpversion(),
				'MySQLVersion'   => $this->wpdb->db_version(),
				'ServerSoftware' => $_SERVER['SERVER_SOFTWARE'],
			),
			'PHP'       => array(
				'MemoryLimit'     => $this->info->get_php_memory_limit(),
				'WP Memory Limit' => $this->info->get_wp_memory_limit(),
				'WP Max Memory'   => $this->info->get_wp_max_memory_limit(),
				'UploadMax'       => ini_get( 'upload_max_filesize' ),
				'PostMax'         => ini_get( 'post_max_size' ),
				'TimeLimit'       => ini_get( 'max_execution_time' ),
				'MaxInputVars'    => ini_get( 'max_input_vars' ),
				'MBString'        => $this->sitepress->get_wp_api()->extension_loaded( 'mbstring' ),
				'libxml'          => $this->sitepress->get_wp_api()->extension_loaded( 'libxml' ),
			) + $this->get_opcache_info(),
		);

		return $core;
	}

	function get_plugins_info() {

		$plugins             = $this->sitepress->get_wp_api()->get_plugins();
		$active_plugins      = $this->sitepress->get_wp_api()->get_option( 'active_plugins' );
		$active_plugins_info = array();

		foreach ( $active_plugins as $plugin ) {
			if ( isset( $plugins[ $plugin ] ) ) {
				unset( $plugins[ $plugin ]['Description'] );
				$active_plugins_info[ $plugin ] = $plugins[ $plugin ];
			}
		}

		$mu_plugins = get_mu_plugins();

		$dropins = get_dropins();

		$output = array(
			'active_plugins' => $active_plugins_info,
			'mu_plugins'     => $mu_plugins,
			'dropins'        => $dropins,
		);

		return $output;
	}

	function get_theme_info() {

		if ( $this->sitepress->get_wp_api()->get_bloginfo( 'version' ) < '3.4' ) {
			/** @var \WP_Theme $current_theme */
			$current_theme = get_theme_data( get_stylesheet_directory() . '/style.css' );
			$theme         = $current_theme;
			unset( $theme['Description'] );
			unset( $theme['Status'] );
			unset( $theme['Tags'] );
		} else {
			$theme = array(
				'Name'       => $this->sitepress->get_wp_api()->get_theme_name(),
				'ThemeURI'   => $this->sitepress->get_wp_api()->get_theme_URI(),
				'Author'     => $this->sitepress->get_wp_api()->get_theme_author(),
				'AuthorURI'  => $this->sitepress->get_wp_api()->get_theme_authorURI(),
				'Template'   => $this->sitepress->get_wp_api()->get_theme_template(),
				'Version'    => $this->sitepress->get_wp_api()->get_theme_version(),
				'TextDomain' => $this->sitepress->get_wp_api()->get_theme_textdomain(),
				'DomainPath' => $this->sitepress->get_wp_api()->get_theme_domainpath(),
				'ParentName' => $this->sitepress->get_wp_api()->get_theme_parent_name(),
			);
		}

		return $theme;
	}

	function do_json_encode( $data ) {
		$json_options = 0;
		if ( defined( 'JSON_HEX_TAG' ) ) {
			$json_options += JSON_HEX_TAG;
		}
		if ( defined( 'JSON_HEX_APOS' ) ) {
			$json_options += JSON_HEX_APOS;
		}
		if ( defined( 'JSON_HEX_QUOT' ) ) {
			$json_options += JSON_HEX_QUOT;
		}
		if ( defined( 'JSON_HEX_AMP' ) ) {
			$json_options += JSON_HEX_AMP;
		}
		if ( defined( 'JSON_UNESCAPED_UNICODE' ) ) {
			$json_options += JSON_UNESCAPED_UNICODE;
		}

		if ( version_compare( $this->sitepress->get_wp_api()->phpversion(), '5.3.0', '<' ) ) {
			$json_data = wp_json_encode( $data );
		} else {
			$json_data = wp_json_encode( $data, $json_options );
		}

		return $json_data;
	}

	/**
	 * Get OPcache status information
	 *
	 * @return array OPcache status details
	 */
	function get_opcache_info() {
		$opcache_info = array();

		// Check if OPcache extension is loaded
		if ( ! function_exists( 'opcache_get_status' ) ) {
			$opcache_info['OPcache'] = 'Not Installed';
			return $opcache_info;
		}

		// Get OPcache status (false = don't include script details)
		$status = @opcache_get_status( false );

		// If status is false, OPcache is installed but disabled or restricted
		if ( false === $status ) {
			$opcache_info['OPcache'] = 'Installed but Disabled';
			return $opcache_info;
		}

		// OPcache is enabled
		$opcache_info['OPcache'] = 'Enabled';

		// Add memory usage statistics if available
		if ( isset( $status['memory_usage'] ) ) {
			$memory = $status['memory_usage'];

			// used_memory: Total bytes currently used by OPcache to store compiled scripts
			$used_memory_mb = isset( $memory['used_memory'] )
				? round( $memory['used_memory'] / 1024 / 1024, 2 )
				: 0;

			// free_memory: Total bytes still available for caching more scripts
			$free_memory_mb = isset( $memory['free_memory'] )
				? round( $memory['free_memory'] / 1024 / 1024, 2 )
				: 0;

			// wasted_memory: Bytes wasted due to restarts or invalidated scripts
			$wasted_memory_mb = isset( $memory['wasted_memory'] )
				? round( $memory['wasted_memory'] / 1024 / 1024, 2 )
				: 0;

			// current_wasted_percentage: Percentage of memory that is wasted
			$wasted_percentage = isset( $memory['current_wasted_percentage'] )
				? round( $memory['current_wasted_percentage'], 2 )
				: 0;

			// Calculate total memory and usage percentage
			$total_memory_mb   = $used_memory_mb + $free_memory_mb + $wasted_memory_mb;
			$usage_percentage  = $total_memory_mb > 0
				? round( ( $used_memory_mb / $total_memory_mb ) * 100, 2 )
				: 0;

			$opcache_info['Memory Used']       = $used_memory_mb . ' MB';
			$opcache_info['Memory Free']       = $free_memory_mb . ' MB';
			$opcache_info['Memory Wasted']     = $wasted_memory_mb . ' MB (' . $wasted_percentage . '%)';
			$opcache_info['Memory Total']      = $total_memory_mb . ' MB';
			$opcache_info['Memory Usage']      = $usage_percentage . '%';
		}

		// Add hit/miss statistics if available
		if ( isset( $status['opcache_statistics'] ) ) {
			$stats = $status['opcache_statistics'];

			// hits: Number of times a script was served from cache (fast path)
			$hits = isset( $stats['hits'] ) ? $stats['hits'] : 0;

			// misses: Number of times a script was not in cache and had to be compiled
			$misses = isset( $stats['misses'] ) ? $stats['misses'] : 0;

			// Calculate hit rate percentage
			$total_requests = $hits + $misses;
			$hit_rate       = $total_requests > 0
				? round( ( $hits / $total_requests ) * 100, 2 )
				: 0;

			$opcache_info['Cache Hits']   = number_format( $hits );
			$opcache_info['Cache Misses'] = number_format( $misses );
			$opcache_info['Hit Rate']     = $hit_rate . '%';

			// num_cached_scripts: Total number of scripts currently cached
			if ( isset( $stats['num_cached_scripts'] ) ) {
				$opcache_info['Cached Scripts'] = number_format( $stats['num_cached_scripts'] );
			}
		}

		return $opcache_info;
	}
}
