<?php
namespace Api\Auth;

use Api\Core\Config;
use Api\Core\Request;

class ApiTokenAuthenticator
{
    private Config $config;

    public function __construct(Config $config)
    {
        $this->config = $config;
    }

    public function authenticate(Request $request): void
    {
        $authorizationHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ?? '';
        if (!$authorizationHeader) {
            throw new \Exception('Missing Authorization header');
        }

        // Basic authorization formal test
        if (!preg_match('/^Basic\s+(.*)$/i', trim($authorizationHeader), $matches)) {
            throw new \Exception('Invalid Authorization header format');
        }
        // Username and password test
        $decoded = explode(':', base64_decode($matches[1]), 2);
        $authorized = empty(array_diff([ $this->config->secret('api_access_username'), $this->config->secret('api_access_password')], $decoded));
        if (!$authorized) {
            throw new \Exception('Authorization failed');
        }

        // Now, for the X-API-Key only if it was defined in the config (simple way to disable it for testing)
        $expectedApiKey = $this->config->secret('api_access_token');
        if ($expectedApiKey !== null && trim($expectedApiKey) !== '') {
            $apiKeyHeader = $_SERVER['HTTP_X_API_KEY'] ?? $_SERVER['REDIRECT_HTTP_X_API_KEY'] ?? '';
            if (!$apiKeyHeader) {
                throw new \Exception('Missing API access token');
            }
            if (!hash_equals((string) $expectedApiKey, (string) $apiKeyHeader)) {
                throw new \Exception('Invalid API access token');
            }
        }
    }
}
