<?php

declare(strict_types=1);

namespace App\Administration\Infrastructure\Service;

use App\Administration\Application\Port\GeoLocationService;
use App\Administration\Domain\Model\Session\Location;

use const FILTER_FLAG_NO_PRIV_RANGE;
use const FILTER_FLAG_NO_RES_RANGE;
use const FILTER_VALIDATE_IP;

/**
 * Null implementation of GeoLocationService.
 *
 * Always returns Location::unknown(). Use this when:
 * - No geolocation database is configured
 * - In development/test environments
 * - When privacy concerns require disabling geolocation
 *
 * For production, replace with MaxMindGeoLocationService
 * or another IP geolocation provider.
 *
 * @see Story 1.6 - Gestion des sessions
 */
final readonly class NullGeoLocationService implements GeoLocationService
{
    public function locate(string $ipAddress): Location
    {
        // Store IP but don't resolve location
        // This allows for future resolution if a geo service is configured
        if ($this->isPrivateOrReserved($ipAddress)) {
            return Location::unknown();
        }

        return Location::fromIp($ipAddress, null, null);
    }

    private function isPrivateOrReserved(string $ip): bool
    {
        return filter_var(
            $ip,
            FILTER_VALIDATE_IP,
            FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE,
        ) === false;
    }
}
