<?php

declare(strict_types=1);

namespace Acms\Services\Installer;

/**
 * インストーラーの .htaccess 有効化判定（W7）。
 *
 * 現行は「ルート .htaccess の存在」だけを必須チェックしていたが、直アクセス防止は php/lang 等
 * 配置対象すべてで効いていないと意味がない。ここでは配置対象ディレクトリごとの存在有無と
 * サーバ種別（Apache か）から、各ディレクトリの状態（ok/error/warn/skip）を返す。
 *
 * .htaccess は Apache 系でのみ有効なため、非 Apache（nginx 等）では必須化してインストールを
 * 止めるのは不適切。非 Apache は一律 skip とし、別途サーバ設定を促す運用とする。
 *
 * ディレクトリの存在確認・サーバ種別判定という副作用（I/O・$_SERVER）は呼び出し側に置き、
 * 本クラスは真偽の組み合わせから状態を導くだけの純粋ロジックとする。
 */
final class HtaccessGuardStatus
{
    public const STATUS_OK = 'ok';
    public const STATUS_ERROR = 'error';
    public const STATUS_WARN = 'warn';
    public const STATUS_SKIP = 'skip';

    /**
     * 配置対象ディレクトリ群を評価し、path => status の連想配列を返す。
     *
     * @param list<array{path: string, present: bool, required: bool}> $directories
     * @param bool $isApache Apache 系サーバか（.htaccess が有効か）
     * @return array<string, string> path => STATUS_*
     */
    public function evaluate(array $directories, bool $isApache): array
    {
        $result = [];
        foreach ($directories as $directory) {
            $result[$directory['path']] = $this->statusFor(
                $directory['present'],
                $directory['required'],
                $isApache
            );
        }

        return $result;
    }

    /**
     * evaluate() の結果に、インストール続行を妨げる error が含まれるか。
     *
     * @param array<string, string> $statuses
     */
    public function hasBlockingError(array $statuses): bool
    {
        return in_array(self::STATUS_ERROR, $statuses, true);
    }

    private function statusFor(bool $present, bool $required, bool $isApache): string
    {
        if (!$isApache) {
            return self::STATUS_SKIP;
        }
        if ($present) {
            return self::STATUS_OK;
        }

        return $required ? self::STATUS_ERROR : self::STATUS_WARN;
    }
}
