// DNS Resource Record type registry.
// Maps between numeric RR types and their metadata.

///|
pub struct RrTypeInfo {
  rtype : UInt16
  name : String
  description : String
  is_domain_based : Bool // True if RDATA contains domain names
}

// Well-known record type registry

///|
pub fn rr_type_registry() -> Array[RrTypeInfo] {
  [
    {
      rtype: 1,
      name: "A",
      description: "IPv4 host address",
      is_domain_based: false,
    },
    {
      rtype: 2,
      name: "NS",
      description: "Authoritative name server",
      is_domain_based: true,
    },
    {
      rtype: 3,
      name: "MD",
      description: "Mail destination (obsolete)",
      is_domain_based: true,
    },
    {
      rtype: 4,
      name: "MF",
      description: "Mail forwarder (obsolete)",
      is_domain_based: true,
    },
    {
      rtype: 5,
      name: "CNAME",
      description: "Canonical name for an alias",
      is_domain_based: true,
    },
    {
      rtype: 6,
      name: "SOA",
      description: "Start of a zone of authority",
      is_domain_based: true,
    },
    {
      rtype: 7,
      name: "MB",
      description: "Mailbox domain name (experimental)",
      is_domain_based: true,
    },
    {
      rtype: 8,
      name: "MG",
      description: "Mail group member (experimental)",
      is_domain_based: true,
    },
    {
      rtype: 9,
      name: "MR",
      description: "Mail rename domain (experimental)",
      is_domain_based: true,
    },
    {
      rtype: 10,
      name: "NULL",
      description: "Null RR (experimental)",
      is_domain_based: false,
    },
    {
      rtype: 11,
      name: "WKS",
      description: "Well known service description",
      is_domain_based: false,
    },
    {
      rtype: 12,
      name: "PTR",
      description: "Domain name pointer",
      is_domain_based: true,
    },
    {
      rtype: 13,
      name: "HINFO",
      description: "Host information",
      is_domain_based: false,
    },
    {
      rtype: 14,
      name: "MINFO",
      description: "Mailbox or mail list information",
      is_domain_based: true,
    },
    {
      rtype: 15,
      name: "MX",
      description: "Mail exchange",
      is_domain_based: true,
    },
    {
      rtype: 16,
      name: "TXT",
      description: "Text strings",
      is_domain_based: false,
    },
    {
      rtype: 17,
      name: "RP",
      description: "Responsible person",
      is_domain_based: true,
    },
    {
      rtype: 18,
      name: "AFSDB",
      description: "AFS database location",
      is_domain_based: true,
    },
    {
      rtype: 19,
      name: "X25",
      description: "X.25 PSDN address",
      is_domain_based: false,
    },
    {
      rtype: 20,
      name: "ISDN",
      description: "ISDN address",
      is_domain_based: false,
    },
    {
      rtype: 21,
      name: "RT",
      description: "Route through",
      is_domain_based: true,
    },
    {
      rtype: 22,
      name: "NSAP",
      description: "NSAP address",
      is_domain_based: false,
    },
    {
      rtype: 24,
      name: "SIG",
      description: "Security signature",
      is_domain_based: false,
    },
    {
      rtype: 25,
      name: "KEY",
      description: "Security key",
      is_domain_based: false,
    },
    {
      rtype: 26,
      name: "PX",
      description: "X.400 mail mapping",
      is_domain_based: true,
    },
    {
      rtype: 27,
      name: "GPOS",
      description: "Geographical position",
      is_domain_based: false,
    },
    {
      rtype: 28,
      name: "AAAA",
      description: "IPv6 host address",
      is_domain_based: false,
    },
    {
      rtype: 29,
      name: "LOC",
      description: "Location information",
      is_domain_based: false,
    },
    {
      rtype: 33,
      name: "SRV",
      description: "Service locator",
      is_domain_based: true,
    },
    {
      rtype: 35,
      name: "NAPTR",
      description: "Naming authority pointer",
      is_domain_based: true,
    },
    {
      rtype: 36,
      name: "KX",
      description: "Key exchanger",
      is_domain_based: true,
    },
    {
      rtype: 37,
      name: "CERT",
      description: "Certificate",
      is_domain_based: false,
    },
    {
      rtype: 39,
      name: "DNAME",
      description: "Delegation name",
      is_domain_based: true,
    },
    {
      rtype: 41,
      name: "OPT",
      description: "EDNS option (pseudo-RR)",
      is_domain_based: false,
    },
    {
      rtype: 43,
      name: "DS",
      description: "Delegation signer",
      is_domain_based: false,
    },
    {
      rtype: 44,
      name: "SSHFP",
      description: "SSH key fingerprint",
      is_domain_based: false,
    },
    {
      rtype: 45,
      name: "IPSECKEY",
      description: "IPSEC key",
      is_domain_based: true,
    },
    {
      rtype: 46,
      name: "RRSIG",
      description: "DNSSEC signature",
      is_domain_based: false,
    },
    {
      rtype: 47,
      name: "NSEC",
      description: "Next secure record",
      is_domain_based: true,
    },
    {
      rtype: 48,
      name: "DNSKEY",
      description: "DNS key",
      is_domain_based: false,
    },
    {
      rtype: 50,
      name: "NSEC3",
      description: "NSEC version 3",
      is_domain_based: true,
    },
    {
      rtype: 51,
      name: "NSEC3PARAM",
      description: "NSEC3 parameters",
      is_domain_based: false,
    },
    {
      rtype: 52,
      name: "TLSA",
      description: "TLSA certificate association",
      is_domain_based: false,
    },
    {
      rtype: 53,
      name: "SMIMEA",
      description: "S/MIME cert association",
      is_domain_based: false,
    },
    {
      rtype: 55,
      name: "HIP",
      description: "Host identity protocol",
      is_domain_based: true,
    },
    { rtype: 59, name: "CDS", description: "Child DS", is_domain_based: false },
    {
      rtype: 60,
      name: "CDNSKEY",
      description: "Child DNSKEY",
      is_domain_based: false,
    },
    {
      rtype: 61,
      name: "OPENPGPKEY",
      description: "OpenPGP public key",
      is_domain_based: false,
    },
    {
      rtype: 62,
      name: "CSYNC",
      description: "Child-to-parent synchronization",
      is_domain_based: false,
    },
    {
      rtype: 63,
      name: "ZONEMD",
      description: "Zone message digest",
      is_domain_based: false,
    },
    {
      rtype: 64,
      name: "SVCB",
      description: "Service binding",
      is_domain_based: true,
    },
    {
      rtype: 65,
      name: "HTTPS",
      description: "HTTPS service binding",
      is_domain_based: true,
    },
    {
      rtype: 99,
      name: "SPF",
      description: "Sender policy framework",
      is_domain_based: false,
    },
    {
      rtype: 108,
      name: "EUI48",
      description: "MAC address (EUI-48)",
      is_domain_based: false,
    },
    {
      rtype: 109,
      name: "EUI64",
      description: "MAC address (EUI-64)",
      is_domain_based: false,
    },
    {
      rtype: 249,
      name: "TKEY",
      description: "Transaction key",
      is_domain_based: false,
    },
    {
      rtype: 250,
      name: "TSIG",
      description: "Transaction signature",
      is_domain_based: false,
    },
    {
      rtype: 251,
      name: "IXFR",
      description: "Incremental zone transfer",
      is_domain_based: false,
    },
    {
      rtype: 252,
      name: "AXFR",
      description: "Full zone transfer",
      is_domain_based: false,
    },
    {
      rtype: 255,
      name: "ANY",
      description: "Request for all records (*)",
      is_domain_based: false,
    },
    {
      rtype: 256,
      name: "URI",
      description: "Uniform resource identifier",
      is_domain_based: false,
    },
    {
      rtype: 257,
      name: "CAA",
      description: "Certification authority authorization",
      is_domain_based: false,
    },
    {
      rtype: 32768,
      name: "TA",
      description: "DNSSEC trust authorities",
      is_domain_based: false,
    },
    {
      rtype: 32769,
      name: "DLV",
      description: "DNSSEC lookaside validation",
      is_domain_based: false,
    },
  ]
}

// Look up an RR type by its numeric value

///|
pub fn lookup_rr_type(rtype : UInt16) -> RrTypeInfo? {
  let registry = rr_type_registry()
  for info in registry {
    if info.rtype == rtype {
      return Some(info)
    }
  }
  None
}

// Check if an RR type requires domain name decompression in RDATA

///|
pub fn rr_type_needs_decompression(rtype : UInt16) -> Bool {
  // Types that contain domain names in RDATA
  match rtype {
    2 => true // NS
    5 => true // CNAME
    6 => true // SOA
    12 => true // PTR
    15 => true // MX
    33 => true // SRV
    39 => true // DNAME
    _ => false
  }
}