<?php

namespace WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Entities;

use WP_Ultimo\Dependencies\RemotelyLiving\PHPDNS\Exceptions\InvalidArgumentException;
use function filter_var;
use function idn_to_ascii;
use function idn_to_utf8;
use function mb_strtolower;
use function substr;
use function trim;
final class Hostname extends EntityAbstract
{
    private string $hostname;
    /**
     * @throws \RemotelyLiving\PHPDNS\Exceptions\InvalidArgumentException
     */
    public function __construct(string $hostname)
    {
        $hostname = $this->normalizeHostName($hostname);
        if (filter_var($hostname, \FILTER_VALIDATE_DOMAIN) !== $hostname) {
            throw new InvalidArgumentException("{$hostname} is not a valid hostname");
        }
        $this->hostname = $hostname;
    }
    public function __toString() : string
    {
        return $this->hostname;
    }
    public function equals(Hostname $hostname) : bool
    {
        return $this->hostname === (string) $hostname;
    }
    public static function createFromString(string $hostname) : Hostname
    {
        return new self($hostname);
    }
    public function getHostName() : string
    {
        return $this->hostname;
    }
    public function getHostnameWithoutTrailingDot() : string
    {
        return substr($this->hostname, 0, -1);
    }
    public function isPunycoded() : bool
    {
        return $this->toUTF8() !== $this->hostname;
    }
    public function toUTF8() : string
    {
        return (string) idn_to_utf8($this->hostname, \IDNA_ERROR_PUNYCODE, \INTL_IDNA_VARIANT_UTS46);
    }
    private static function punyCode(string $hostname) : string
    {
        return (string) idn_to_ascii($hostname, \IDNA_ERROR_PUNYCODE, \INTL_IDNA_VARIANT_UTS46);
    }
    private function normalizeHostName(string $hostname) : string
    {
        $hostname = self::punyCode(mb_strtolower(trim($hostname)));
        if (substr($hostname, -1) !== '.') {
            return "{$hostname}.";
        }
        return $hostname;
    }
}
