<?php
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * RSS 使用済み履歴管理
 *
 * フィードごとに最新 HISTORY_PER_FEED 件の guid を FIFO で保持する。
 * aiap_rss_state option を独占管理する（直接 get_option を呼ばないこと）。
 *
 * 構造:
 *   array(
 *       'feed_xxx' => array( 'used_guids' => array( 'guid1', 'guid2', ... ) ),
 *       ...
 *   )
 */
class AIAP_RSS_State {

    const OPTION_KEY        = 'aiap_rss_state';
    const HISTORY_PER_FEED  = 500;

    /**
     * 全状態を取得
     *
     * @return array
     */
    public static function get_all() {
        $state = get_option( self::OPTION_KEY, array() );
        return is_array( $state ) ? $state : array();
    }

    /**
     * 全状態を保存（autoload=no）
     *
     * @param array $state
     */
    private static function save_all( array $state ) {
        update_option( self::OPTION_KEY, $state, false );
    }

    /**
     * 指定フィードで guid が使用済みか
     *
     * @param string $feed_id
     * @param string $guid
     * @return bool
     */
    public static function is_used( $feed_id, $guid ) {
        if ( $feed_id === '' || $guid === '' ) {
            return false;
        }
        $state = self::get_all();
        if ( ! isset( $state[ $feed_id ]['used_guids'] ) || ! is_array( $state[ $feed_id ]['used_guids'] ) ) {
            return false;
        }
        return in_array( $guid, $state[ $feed_id ]['used_guids'], true );
    }

    /**
     * guid を使用済みとしてマーク（FIFO 500 件、冪等）
     *
     * @param string $feed_id
     * @param string $guid
     * @param int    $post_id   将来の拡張用（現状未使用、postmeta 側で post→guid を辿るため）
     */
    public static function mark_used( $feed_id, $guid, $post_id = 0 ) {
        if ( $feed_id === '' || $guid === '' ) {
            return;
        }
        $state = self::get_all();
        if ( ! isset( $state[ $feed_id ] ) || ! is_array( $state[ $feed_id ] ) ) {
            $state[ $feed_id ] = array( 'used_guids' => array() );
        }
        if ( ! isset( $state[ $feed_id ]['used_guids'] ) || ! is_array( $state[ $feed_id ]['used_guids'] ) ) {
            $state[ $feed_id ]['used_guids'] = array();
        }
        // 冪等性
        if ( in_array( $guid, $state[ $feed_id ]['used_guids'], true ) ) {
            return;
        }
        $state[ $feed_id ]['used_guids'][] = $guid;
        // FIFO トリム
        $count = count( $state[ $feed_id ]['used_guids'] );
        if ( $count > self::HISTORY_PER_FEED ) {
            $state[ $feed_id ]['used_guids'] = array_slice(
                $state[ $feed_id ]['used_guids'],
                $count - self::HISTORY_PER_FEED
            );
        }
        self::save_all( $state );
        unset( $post_id ); // 将来拡張のための予約引数（PHP の "未使用引数" 警告対策）
    }

    /**
     * 指定フィードの履歴をすべて削除（フィード削除時、または UI からの履歴クリア時に呼ぶ）
     *
     * @param string $feed_id
     * @return int 削除した guid 件数（0 ならエントリ無し）
     */
    public static function purge_feed( $feed_id ) {
        if ( $feed_id === '' ) {
            return 0;
        }
        $state = self::get_all();
        if ( ! isset( $state[ $feed_id ]['used_guids'] ) ) {
            return 0;
        }
        $count = count( $state[ $feed_id ]['used_guids'] );
        unset( $state[ $feed_id ] );
        self::save_all( $state );
        return $count;
    }

    /**
     * 指定フィードの使用済み件数を返す（UI 表示用）
     *
     * @param string $feed_id
     * @return int
     */
    public static function count_used( $feed_id ) {
        if ( $feed_id === '' ) {
            return 0;
        }
        $state = self::get_all();
        return isset( $state[ $feed_id ]['used_guids'] ) && is_array( $state[ $feed_id ]['used_guids'] )
            ? count( $state[ $feed_id ]['used_guids'] )
            : 0;
    }
}
