<?php

declare(strict_types=1);

namespace Acms\Services\Cache;

use Acms\Services\Cache\Adapters\Tag;
use Acms\Services\Facades\Cache;

/**
 * 動的ページのレンダリング結果をページキャッシュへ保存する。
 */
class PageCacheWriter
{
    /**
     * ページキャッシュのアダプタ
     *
     * @var Tag|null
     */
    private $pageCache;

    /**
     * Why not saveCache() 内で Cache::page() を直接呼ぶ: テスト環境ではページキャッシュのドライバが
     * memory（phpunit.xml.dist の CACHE_PAGE_DRIVER）で put / getItem が往復しないため、
     * 「どの条件で書き込むか」という本クラスの唯一の責務を検証できない。他の分解クラス
     * （Emitter ← HeaderBuilder、FieldRepository ← FieldExtractor）と同じくアダプタを注入可能にする。
     * 既定 null は、コンテナを経由せず直接 new する既存コードのためのフォールバック。
     *
     * @param Tag|null $pageCache
     */
    public function __construct(?Tag $pageCache = null)
    {
        $this->pageCache = $pageCache;
    }

    /**
     * @param string $chid
     * @param string $contents
     * @param string $mime
     */
    public function saveCache($chid, $contents, $mime)
    {
        $no_cache_page = false;
        $pageCache = $this->pageCache;
        if ($pageCache === null) {
            /** @var Tag $pageCache */
            $pageCache = Cache::page();
        }

        if (
            0
            || (defined('NO_CACHE_PAGE') && NO_CACHE_PAGE)
            || strtoupper($_SERVER['REQUEST_METHOD']) !== 'GET'
        ) {
            $no_cache_page = true;
        }
        if (
            !!$chid &&
            !$no_cache_page &&
            '200 OK' === httpStatusCode()
        ) {
            $tagBid = 'bid-' . BID;
            $tagEid = 'eid-' . EID;
            $value = [
                'mime' => $mime,
                'charset' => config('charset'),
                'createdAt' => REQUEST_TIME,
                'data' => $contents,
            ];
            $lifetime = intval(config('cache_expire'));
            $pageCache->put($chid, $value, $lifetime, [$tagBid, $tagEid]);
        }
    }
}
