<?php

namespace CleantalkSP\SpbctWP\Firewall;

use CleantalkSP\Common\Logger;
use CleantalkSP\Common\LoggerRecord;
use CleantalkSP\SpbctWP\State;

/**
 * Firewall update logger for SPBC WordPress plugin.
 * Stores log records in the plugin's global stats array rather than filesystem.
 */
class SpbcFWUpdateLogger extends Logger
{
    /**
     * @var int Reduced log limit specific to firewall update logs
     */
    protected static $log_limit = 1000;

    /**
     * Store a log record in the global $spbc->fw_stats array.
     * Appends the record to the 'last_update_log' array and persists changes.
     *
     * @inheritDoc
     * @param LoggerRecord $record The log record to store
     * @return void
     */
    public static function updateStorage($record)
    {
        $spbc = self::getState();

        if (!$spbc) {
            return;
        }

        $fw_stats = $spbc->fw_stats instanceof \ArrayObject
            ? $spbc->fw_stats->getArrayCopy()
            : $spbc->fw_stats;
        $log = [];
        if (
            is_array($fw_stats) &&
            isset($fw_stats['last_update_log']) &&
            is_array($fw_stats['last_update_log'])
        ) {
            $log = $fw_stats['last_update_log'];
        }

        // Ensure the record is of correct type before storing
        if ($record instanceof LoggerRecord) {
            // Append new record
            $log[] = $record;

            if (count($log) > static::$log_limit) {
                $log = array_slice($log, -static::$log_limit);
            }

            $spbc->fw_stats['last_update_log'] = $log;

            // Persist changes to database
            $spbc->save('fw_stats', true, false);
        }
    }

    /**
     * Load all firewall update log records from global storage.
     *
     * @inheritDoc
     * @return LoggerRecord[] Array of log records, empty array if none exist
     */
    public static function loadStorage()
    {
        $spbc = self::getState();

        if (!$spbc) {
            return array();
        }

        // Return existing logs or empty array
        return isset($spbc->fw_stats['last_update_log']) && is_array($spbc->fw_stats['last_update_log'])
            ? $spbc->fw_stats['last_update_log']
            : [];
    }

    /**
     * Clear all firewall update log records from storage.
     * Resets the log array and saves the change.
     *
     * @inheritDoc
     * @return void
     * @psalm-suppress PossiblyUnusedMethod
     */
    public static function clearStorage()
    {
        $spbc = self::getState();

        if (!$spbc) {
            return;
        }

        // Reset log array
        $spbc->fw_stats['last_update_log'] = array();

        // Persist empty array to database
        $spbc->save('fw_stats', true, false);
    }

    /**
     * @return State|null
     */
    public static function getState()
    {
        global $spbc;
        if (
            !isset($spbc) ||
            !is_object($spbc) ||
            !method_exists($spbc, 'save')
        ) {
            return null;
        }
        return $spbc;
    }
}
