<?php
/**
 * Persisted index build state (autoload = false).
 *
 * @package LolaCoreForBricks
 */

declare(strict_types=1);

namespace LolaCoreForBricks\Index;

/**
 * Reads and writes lolacore_bricks_index_state.
 */
class IndexState
{
    public const OPTION_KEY = 'lolacore_bricks_index_state';

    /**
     * @return array<string, mixed>
     */
    public function get(): array
    {
        $state = get_option(self::OPTION_KEY, []);

        return is_array($state) ? $this->normalize($state) : $this->defaults();
    }

    /**
     * @param array<string, mixed> $state
     */
    public function save(array $state): void
    {
        update_option(self::OPTION_KEY, $this->normalize($state), false);
    }

    public function reset(): void
    {
        $this->save($this->defaults());
    }

    public function schemaMismatch(): bool
    {
        $state = $this->get();

        return (int) ($state['schema_version'] ?? 0) !== IndexSchema::SCHEMA_VERSION;
    }

    /**
     * @return array<string, mixed>
     */
    private function defaults(): array
    {
        return [
            'schema_version'   => IndexSchema::SCHEMA_VERSION,
            'built_at'         => null,
            'class_stamp'      => null,
            'max_modified'     => null,
            'indexed_pages'    => 0,
            'total_pages'      => 0,
            'post_ids'         => [],
            'post_cursor'      => 0,
            'globals_indexed'  => false,
            'finished'         => false,
            'build_started_at' => null,
        ];
    }

    /**
     * @param array<string, mixed> $state
     * @return array<string, mixed>
     */
    private function normalize(array $state): array
    {
        $defaults = $this->defaults();

        $state['schema_version']  = (int) ($state['schema_version'] ?? $defaults['schema_version']);
        $state['indexed_pages']   = (int) ($state['indexed_pages'] ?? 0);
        $state['total_pages']     = (int) ($state['total_pages'] ?? 0);
        $state['post_cursor']     = (int) ($state['post_cursor'] ?? 0);
        $state['globals_indexed'] = (bool) ($state['globals_indexed'] ?? false);
        $state['finished']        = (bool) ($state['finished'] ?? false);
        $state['post_ids']        = is_array($state['post_ids'] ?? null) ? array_values($state['post_ids']) : [];

        foreach (['built_at', 'class_stamp', 'max_modified', 'build_started_at'] as $key) {
            if (!array_key_exists($key, $state)) {
                $state[$key] = $defaults[$key];
            }
        }

        return $state;
    }
}
