<?php
/*
 * Copyright 2026 Alessandro Chiapparini <sprint_planer_web@chiapparini.org>
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * See the LICENSE file in the project root for the full license text.
 */

declare(strict_types=1);

namespace App\Auth;

/**
 * Env-configured admin fallback for environments where OIDC is not yet
 * (or deliberately not) configured.
 *
 * Enabled iff BOTH env vars are set:
 *     LOCAL_ADMIN_EMAIL
 *     LOCAL_ADMIN_PASSWORD_HASH    (PHP password_hash() output, e.g. bcrypt)
 *
 * Optional:
 *     LOCAL_ADMIN_NAME             display name (default "Local Admin")
 *
 * The hash is generated once at install time with PHP's `password_hash()`
 * (see README's Quick setup) and verified at sign-in with `password_verify()`.
 * Storing only the hash means a leaked `.env` no longer hands an attacker a
 * usable password directly. The corresponding user row is stored with
 *     entra_oid = "local:<email>"
 *     is_admin  = 1
 * so it will not collide with a real Entra user.
 */
final class LocalAdmin
{
    public const OID_PREFIX = 'local:';

    public static function isEnabled(): bool
    {
        return self::email() !== '' && self::passwordHash() !== '';
    }

    public static function email(): string
    {
        $v = getenv('LOCAL_ADMIN_EMAIL');
        return is_string($v) ? trim($v) : '';
    }

    public static function displayName(): string
    {
        $v = getenv('LOCAL_ADMIN_NAME');
        $name = is_string($v) ? trim($v) : '';
        return $name !== '' ? $name : 'Local Admin';
    }

    public static function oid(): string
    {
        return self::OID_PREFIX . self::email();
    }

    /** Timing-safe credential check. Returns false if local admin is disabled. */
    public static function verify(string $email, string $password): bool
    {
        if (!self::isEnabled()) {
            return false;
        }
        $emailMatch = hash_equals(self::email(), trim($email));
        $pwMatch    = password_verify($password, self::passwordHash());
        return $emailMatch && $pwMatch;
    }

    private static function passwordHash(): string
    {
        $v = getenv('LOCAL_ADMIN_PASSWORD_HASH');
        return is_string($v) ? trim($v) : '';
    }
}
