<?php

namespace NoahVet\Reef\Domain\Http\Multipart;

class HeaderValueParser implements HeaderValueParserInterface
{
    #[\Override]
    public function getValue(?string $header): string
    {
        [$value] = $this->parseHeaderContent($header);

        return $value;
    }

    /** @return array<string, string> */
    #[\Override]
    public function getOptions(?string $header): array
    {
        [, $options] = $this->parseHeaderContent($header);

        return $options;
    }

    #[\Override]
    public function getOption(?string $header, string $key, mixed $default = null): mixed
    {
        $options = $this->getOptions($header);

        return $options[$key] ?? $default;
    }

    /** @return array{string, array<string, string>} */
    protected function parseHeaderContent(?string $content): array
    {
        $parts = \explode(';', (string) $content);
        $headerValue = \array_shift($parts);
        $options = [];

        foreach ($parts as $part) {
            if ('' === $part) {
                continue;
            }

            $partSplit = \explode('=', $part, 2);
            if (2 !== \count($partSplit)) {
                $options[$partSplit[0]] = '';
                continue;
            }

            [$key, $value] = $partSplit;

            if ('*' === \substr($key, -1)) {
                // RFC 5987
                $key = \substr($key, 0, -1);
                if (\preg_match(
                    "/(?P<charset>[\w!#$%&+^_`{}~-]+)'(?P<language>[\w-]*)'(?P<value>.*)$/",
                    $value,
                    $matches,
                )) {
                    $value = (string) \mb_convert_encoding(
                        \rawurldecode($matches['value']),
                        'utf-8',
                        $matches['charset'],
                    );
                }
            }

            $options[\trim($key)] = \trim($value, ' "');
        }

        return [$headerValue, $options];
    }
}
