<commit_before><?php

/**
 * PHP Domain Parser: Public Suffix List based URL parsing.
 *
 * @see http://github.com/jeremykendall/php-domain-parser for the canonical source repository
 *
 * @copyright Copyright (c) 2017 <NAME> (http://jeremykendall.net)
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

declare(strict_types=1);

namespace Pdp;

use function array_reverse;
use function array_slice;
use function count;
use function explode;
use function implode;
use function preg_match;
use function sprintf;
use function strlen;
use function substr;

final class ResolvedDomain implements ResolvedDomainName
{
    private const REGEXP_IDN_PATTERN = '/[^\x20-\x7f]/';

    private DomainName $domain;

    private PublicSuffix $publicSuffix;

    private DomainName $registrableDomain;

    private DomainName $subDomain;

    public function __construct(Host $domain, ?PublicSuffix $publicSuffix = null)
    {
        $this->domain = $this->setDomainName($domain);
        $this->publicSuffix = $this->setPublicSuffix($publicSuffix);
        $this->registrableDomain = $this->setRegistrableDomain();
        $this->subDomain = $this->setSubDomain();
    }

    public static function __set_state(array $properties): self
    {
        return new self($properties['domain'], $properties['publicSuffix']);
    }

    private function setDomainName(Host $domain): DomainName
    {
        if (!$domain instanceof DomainName) {
            return new Domain($domain, $domain->getAsciiIDNAOption(), $domain->getUnicodeIDNAOption());
        }

        return $domain;
    }

    /**
     * Sets the public suffix domain part.
     *
     * @throws UnableToResolveDomain If the public suffic can not be attached to the domain
     */
    private function setPublicSuffix(PublicSuffix $publicSuffix = null): PublicSuffix
    {
        $asciiIDNAOptions = $this->domain->getAsciiIDNAOption();
        $unicodeIDNAOptions = $this->domain->getUnicodeIDNAOption();

        if (null === $publicSuffix || null === $publicSuffix->getContent()) {
            return PublicSuffix::fromNull($asciiIDNAOptions, $unicodeIDNAOptions);
        }

        if (2 > count($this->domain)) {
            throw UnableToResolveDomain::dueToUnresolvableDomain($this->domain);
        }

        if ('.' === substr((string) $this->domain, -1, 1)) {
            throw UnableToResolveDomain::dueToUnresolvableDomain($this->domain);
        }

        /** @var string $domainContent */
        $domainContent = $this->domain->getContent();
        $publicSuffix = $this->normalize($publicSuffix);
        /** @var string $psContent */
        $psContent = $publicSuffix->getContent();
        if ($domainContent === $psContent) {
            throw new UnableToResolveDomain(sprintf('The public suffix `%s` can not be equal to the domain name `%s`', $psContent, $this->domain));
        }

        if ('.'.$psContent !== substr($domainContent, - strlen($psContent) - 1)) {
            throw new UnableToResolveDomain(sprintf('The public suffix `%s` can not be assign to the domain name `%s`', $psContent, $this->domain));
        }

        return $publicSuffix;
    }

    /**
     * Normalize the domain name encoding content.
     */
    private function normalize(PublicSuffix $subject): PublicSuffix
    {
        if (1 !== preg_match(self::REGEXP_IDN_PATTERN, $this->domain->__toString())) {
            return $subject->toAscii();
        }

        return $subject->toUnicode();
    }

    /**
     * Computes the registrable domain part.
     */
    private function setRegistrableDomain(): DomainName
    {
        if (null === $this->publicSuffix->getContent()) {
            return Domain::fromNull($this->domain->getAsciiIDNAOption(), $this->domain->getUnicodeIDNAOption());
        }

        $domain = implode('.', array_slice(<commit_msg>Improve ResolvedDomain codebase<commit_after><?php

/**
 * PHP Domain Parser: Public Suffix List based URL parsing.
 *
 * @see http://github.com/jeremykendall/php-domain-parser for the canonical source repository
 *
 * @copyright Copyright (c) 2017 <NAME> (http://jeremykendall.net)
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

declare(strict_types=1);

namespace Pdp;

use function array_reverse;
use function array_slice;
use function count;
use function explode;
use function implode;
use function preg_match;
use function sprintf;
use function strlen;
use function substr;

final class ResolvedDomain implements ResolvedDomainName
{
    private const REGEXP_IDN_PATTERN = '/[^\x20-\x7f]/';

    private DomainName $domain;

    private PublicSuffix $publicSuffix;

    private DomainName $registrableDomain;

    private DomainName $subDomain;

    public function __construct(Host $domain, ?PublicSuffix $publicSuffix = null)
    {
        $this->domain = $this->setDomainName($domain);
        $this->publicSuffix = $this->setPublicSuffix($publicSuffix);
        $this->registrableDomain = $this->setRegistrableDomain();
        $this->subDomain = $this->setSubDomain();
    }

    public static function __set_state(array $properties): self
    {
        return new self($properties['domain'], $properties['publicSuffix']);
    }

    private function setDomainName(Host $domain): DomainName
    {
        if (!$domain instanceof DomainName) {
            return new Domain($domain, $domain->getAsciiIDNAOption(), $domain->getUnicodeIDNAOption());
        }

        return $domain;
    }

    /**
     * Sets the public suffix domain part.
     *
     * @throws UnableToResolveDomain If the public suffic can not be attached to the domain
     */
    private function setPublicSuffix(PublicSuffix $publicSuffix = null): PublicSuffix
    {
        $asciiIDNAOptions = $this->domain->getAsciiIDNAOption();
        $unicodeIDNAOptions = $this->domain->getUnicodeIDNAOption();

        if (null === $publicSuffix || null === $publicSuffix->getContent()) {
            return PublicSuffix::fromNull($asciiIDNAOptions, $unicodeIDNAOptions);
        }

        if (2 > count($this->domain)) {
            throw UnableToResolveDomain::dueToUnresolvableDomain($this->domain);
        }

        if ('.' === substr((string) $this->domain, -1, 1)) {
            throw UnableToResolveDomain::dueToUnresolvableDomain($this->domain);
        }

        $publicSuffix = $this->normalize($publicSuffix);
        if ($this->domain->getContent() === $publicSuffix->getContent()) {
            throw new UnableToResolveDomain(sprintf('The public suffix and the domain name are is identical `%s`.', $this->domain));
        }

        $psContent = (string) $publicSuffix;
        if ('.'.$psContent !== substr((string) $this->domain, - strlen($psContent) - 1)) {
            throw new UnableToResolveDomain(sprintf('The public suffix `%s` can not be assign to the domain name `%s`', $psContent, $this->domain));
        }

        return $publicSuffix;
    }

    /**
     * Normalize the domain name encoding content.
     */
    private function normalize(PublicSuffix $subject): PublicSuffix
    {
        if (1 !== preg_match(self::REGEXP_IDN_PATTERN, $this->domain->__toString())) {
            return $subject->toAscii();
        }

        return $subject->toUnicode();
    }

    /**
     * Computes the registrable domain part.
     */
    private function setRegistrableDomain(): DomainName
    {
        if (null === $this->publicSuffix->getContent()) {
            return Domain::fromNull($this->domain->getAsciiIDNAOption(), $this->domain->getUnicodeIDNAOption());
        }

        $domain = implode('.', array_slice(
{'fraction_non_alphanumeric': 0.12619849701995337, 'fraction_numerical': 0.0033687483804094327, 'mean_word_length': 3.1344402785216925, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 78, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5358831', 'n_tokens_mistral': 2226, 'n_tokens_neox': 2155, 'n_words': 544}