<?php
declare( strict_types=1 );

namespace FiboFilters\Indexer;

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

/**
 * Class Config
 */
class Config {

	const INDEXER_DEBUG_TRANSIENT_KEY       = 'fibofilters_indexer_debug';
	const INDEXER_DEBUG_SCOPE_TRANSIENT_KEY = 'fibofilters_indexer_debug_scope';

	// TODO To będzie dopiero używane na stronie Debug, gdzie będzie można włączyć logowanie poszczególnych zakresów.
	/** @var string[] */
	private $indexer_debug_scopes = [ // @phpstan-ignore-line
		'all',
		'filters',
		'bg-process',
	];

	/** @var string[] */
	private $indexer_modes = [
		'async', // Default mode; indexes are built in parallel.
		'direct', // Indexes are built in one request with no background processes.
	];

	/** @var string */
	private $indexer_mode;

	/** @var string */
	private $index_role = '';

	/**
	 * Get indexer mode
	 *
	 * Modes: 'async', 'direct'.
	 */
	public function get_indexer_mode(): string {
		if ( ! in_array( $this->indexer_mode, $this->indexer_modes, true ) ) {
			$this->indexer_mode = $this->indexer_modes[0];
		}

		$indexer_mode = $this->indexer_mode;

		if ( defined( 'FIBOFILTERS_INDEXER_MODE' ) && in_array( FIBOFILTERS_INDEXER_MODE, $this->indexer_modes, true ) ) {
			$indexer_mode = FIBOFILTERS_INDEXER_MODE;
		}

		/**
		 * Indexer mode.
		 *
		 * @param string $indexer_mode Mode.
		 *
		 * @since 0.0.1
		 */
		$filtered_mode = apply_filters( 'fibofilters/indexer/indexer_mode', $indexer_mode );

		if ( in_array( $filtered_mode, $this->indexer_modes, true ) ) {
			$indexer_mode = $filtered_mode;
		}

		return $indexer_mode;
	}

	/**
	 * Check if indexer is in specific mode
	 *
	 * Modes: 'async', 'direct'.
	 *
	 * @param string $mode Indexer mode.
	 */
	public function is_indexer_mode( string $mode ): bool {
		return $this->get_indexer_mode() === $mode;
	}

	public function set_indexer_mode( string $mode ): void {
		if ( in_array( $mode, $this->indexer_modes, true ) ) {
			$this->indexer_mode = $mode;
		}
	}

	/**
	 * Is indexer debug enabled
	 */
	public function is_debug(): bool {
		if ( defined( 'FIBOFILTERS_INDEXER_DEBUG' ) ) {
			return (bool) FIBOFILTERS_INDEXER_DEBUG;
		}

		return (bool) get_transient( self::INDEXER_DEBUG_TRANSIENT_KEY );
	}

	/**
	 * Get indexer debug scope
	 */
	public function get_debug_scopes(): array {
		if ( defined( 'FIBOFILTERS_INDEXER_DEBUG_SCOPE' ) ) {
			$scope = explode( ',', FIBOFILTERS_INDEXER_DEBUG_SCOPE );

			return array_map( 'trim', $scope );
		}

		$scope = get_transient( self::INDEXER_DEBUG_SCOPE_TRANSIENT_KEY );

		return is_array( $scope ) ? $scope : [ 'all' ];
	}

	/**
	 * Check if scope of debug is enabled
	 *
	 * @param string $scope Debug scope.
	 */
	public function is_debug_scope_active( string $scope ): bool {
		if ( $scope === 'all' || in_array( 'all', $this->get_debug_scopes(), true ) ) {
			return true;
		}

		return in_array( $scope, $this->get_debug_scopes(), true );
	}

	/**
	 * Check if parallel index building is enabled
	 */
	public function is_parallel_building_enabled(): bool {
		$parallel = true;

		if ( defined( 'FIBOFILTERS_PARALLEL_INDEX_BUILD' ) && ! FIBOFILTERS_PARALLEL_INDEX_BUILD ) {
			$parallel = false;
		}

		return $parallel;
	}

	/**
	 * Get index role
	 */
	public function get_index_role(): string {
		if ( in_array( $this->index_role, [ 'tmp', 'main' ], true ) ) {
			return $this->index_role;
		}

		$this->index_role = $this->is_parallel_building_enabled() ? 'tmp' : 'main';

		return $this->index_role;
	}
}
