<?php

declare(strict_types=1);

namespace App\Framework\Http\ValueObjects;

use App\Framework\Http\IpAddress;

final readonly class IpPatternCollection
{
    /** @param array<IpPattern> $patterns */
    private function __construct(
        private array $patterns
    ) {
    }

    public static function fromArray(array $patterns): self
    {
        $ipPatterns = array_map(
            fn (string $pattern) => IpPattern::fromString($pattern),
            $patterns
        );

        return new self($ipPatterns);
    }

    public static function empty(): self
    {
        return new self([]);
    }

    public static function single(string $pattern): self
    {
        return new self([IpPattern::fromString($pattern)]);
    }

    public function contains(IpAddress $ip): bool
    {
        foreach ($this->patterns as $pattern) {
            if ($pattern->matches($ip)) {
                return true;
            }
        }

        return false;
    }

    public function toArray(): array
    {
        return array_map(
            fn (IpPattern $pattern) => $pattern->toString(),
            $this->patterns
        );
    }

    public function isEmpty(): bool
    {
        return empty($this->patterns);
    }

    public function add(string $pattern): self
    {
        $patterns = $this->patterns;
        $patterns[] = IpPattern::fromString($pattern);

        return new self($patterns);
    }

    public function merge(self $other): self
    {
        return new self(array_merge($this->patterns, $other->patterns));
    }

    public function count(): int
    {
        return count($this->patterns);
    }
}
