<?php

declare(strict_types=1);

namespace App\Framework\Core\ValueObjects;

enum Port: int
{
    case HTTP = 80;
    case HTTPS = 443;
    case FTP = 21;
    case SSH = 22;
    case SMTP = 25;
    case DNS = 53;
    case DHCP = 67;
    case POP3 = 110;
    case IMAP = 143;
    case SNMP = 161;
    case LDAP = 389;
    case SMTPS = 465;
    case IMAPS = 993;
    case POP3S = 995;
    case MYSQL = 3306;
    case POSTGRESQL = 5432;
    case REDIS = 6379;
    case MONGODB = 27017;

    public static function forScheme(string $scheme): ?self
    {
        return match (strtolower($scheme)) {
            'http' => self::HTTP,
            'https' => self::HTTPS,
            'ftp' => self::FTP,
            'ssh' => self::SSH,
            'smtp' => self::SMTP,
            'pop3' => self::POP3,
            'imap' => self::IMAP,
            'ldap' => self::LDAP,
            default => null,
        };
    }

    public function getScheme(): ?string
    {
        return match ($this) {
            self::HTTP => 'http',
            self::HTTPS => 'https',
            self::FTP => 'ftp',
            self::SSH => 'ssh',
            self::SMTP => 'smtp',
            self::POP3 => 'pop3',
            self::IMAP => 'imap',
            self::LDAP => 'ldap',
            default => null,
        };
    }

    public function getName(): string
    {
        return match ($this) {
            self::HTTP => 'HTTP',
            self::HTTPS => 'HTTPS',
            self::FTP => 'FTP',
            self::SSH => 'SSH',
            self::SMTP => 'SMTP',
            self::DNS => 'DNS',
            self::DHCP => 'DHCP',
            self::POP3 => 'POP3',
            self::IMAP => 'IMAP',
            self::SNMP => 'SNMP',
            self::LDAP => 'LDAP',
            self::SMTPS => 'SMTPS',
            self::IMAPS => 'IMAPS',
            self::POP3S => 'POP3S',
            self::MYSQL => 'MySQL',
            self::POSTGRESQL => 'PostgreSQL',
            self::REDIS => 'Redis',
            self::MONGODB => 'MongoDB',
        };
    }

    public function isSecure(): bool
    {
        return match ($this) {
            self::HTTPS, self::SSH, self::SMTPS, self::IMAPS, self::POP3S => true,
            default => false,
        };
    }

    public function isWellKnown(): bool
    {
        return $this->value < 1024;
    }

    public static function isValidPort(int $port): bool
    {
        return $port >= 1 && $port <= 65535;
    }
}
