<?php

declare(strict_types=1);

namespace Numinix\SeekmodoWordPress\Storage;

use Numinix\SeekmodoSdk\Storage\BreakerStateStore;

/**
 * WordPress-flavoured implementation of the SDK's
 * {@see BreakerStateStore} interface, backed by WP transients.
 *
 * WP transients are the standard "fast, shared, expirable" store
 * inside WordPress: they live in `wp_options` by default but get
 * promoted to the object-cache backend (Memcached, Redis, etc.)
 * automatically when a persistent object cache is installed — which
 * is exactly the behaviour we want for a circuit breaker that must
 * be coherent across php-fpm workers on production hosts and not
 * lose its mind on a vanilla WP install.
 *
 * The transient name is prefixed with `seekmodo_breaker_` so an
 * operator inspecting `wp_options` can grep for the connector's
 * runtime rows.
 */
final class WpTransientBreakerStore implements BreakerStateStore
{
    public const TRANSIENT_PREFIX = 'seekmodo_breaker_';

    public function load(string $key): array
    {
        $default = [
            'state' => 'closed',
            'failures' => [],
            'opened_at' => 0,
            'probe_in_flight' => false,
        ];

        if (!function_exists('get_transient')) {
            return $default;
        }
        $raw = get_transient(self::TRANSIENT_PREFIX . $key);
        if (!is_array($raw)) {
            return $default;
        }
        return [
            'state' => (string) ($raw['state'] ?? 'closed'),
            'failures' => array_values(array_map('intval', (array) ($raw['failures'] ?? []))),
            'opened_at' => (int) ($raw['opened_at'] ?? 0),
            'probe_in_flight' => (bool) ($raw['probe_in_flight'] ?? false),
        ];
    }

    public function save(string $key, array $state, int $ttlSeconds): void
    {
        if (!function_exists('set_transient')) {
            return;
        }
        set_transient(self::TRANSIENT_PREFIX . $key, $state, max(1, $ttlSeconds));
    }
}
