<?php
declare(strict_types=1);

namespace SafeTun\Backend\Net;

final class CidrMatcher
{
    /** @var list<IpNetwork> */
    private array $allowed;
    /** @var list<IpNetwork> */
    private array $denied;

    /** @param list<string> $allowed @param list<string> $denied */
    public function __construct(array $allowed, array $denied = [])
    {
        $this->allowed = array_map(static fn (string $cidr): IpNetwork => IpNetwork::parse($cidr), $allowed);
        $this->denied = array_map(static fn (string $cidr): IpNetwork => IpNetwork::parse($cidr), $denied);
    }

    public function isAllowed(string $address, bool $dangerouslyAllowAll = false): bool
    {
        foreach ($this->denied as $network) {
            if ($network->contains($address)) {
                return false;
            }
        }

        foreach ($this->allowed as $network) {
            if ($network->contains($address)) {
                return true;
            }
        }

        return $dangerouslyAllowAll;
    }

    /** @param list<string> $cidrs */
    public static function containsAny(array $cidrs, string $address): bool
    {
        foreach ($cidrs as $cidr) {
            if (IpNetwork::parse($cidr)->contains($address)) {
                return true;
            }
        }
        return false;
    }
}
