mod parse;
mod message;

use message::{Header};
use uri::HostName;

use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};

#[derive(Debug,Copy,Clone)]
pub enum Error {
    ServerNotFound,
    RecordNotFound,
    ConnectionTerminated,
}


pub type Result<T> = std::result::Result<T, Error>;

#[repr(u16)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RecordType {
    Reserved = 0,
    A = 1,
    NS = 2,
    MD = 3,
    MF = 4,
    CNAME = 5,
    SOA = 6,
    MB = 7,
    MG = 8,
    MR = 9,
    NULL = 10,
    WKS = 11,
    PTR = 12,
    HINFO = 13,
    MINFO = 14,
    MX = 15,
    TXT = 16,
    RP = 17,
    AFSDB = 18,
    X25 = 19,
    ISDN = 20,
    RT = 21,
    NSAP = 22,
    NSAP_PTR = 23,
    SIG = 24,
    KEY = 25,
    PX = 26,
    GPOS = 27,
    AAAA = 28,
    LOC = 29,
    NXT = 30,
    EID = 31,
    NIMLOC = 32,
    SRV = 33,
    ATMA = 34,
    NAPTR = 35,
    KX = 36,
    CERT = 37,
    A6 = 38,
    DNAME = 39,
    SINK = 40,
    OPT = 41,
    APL = 42,
    DS = 43,
    SSHFP = 44,
    IPSECKEY = 45,
    RRSIG = 46,
    NSEC = 47,
    DNSKEY = 48,
    DHCID = 49,
    NSEC3 = 50,
    NSEC3PARAM = 51,
    TLSA = 52,
    SMIMEA = 53,
    HIP = 55,
    NINFO = 56,
    RKEY = 57,
    TALINK = 58,
    CDS = 59,
    CDNSKEY = 60,
    OPENPGPKEY = 61,
    CSYNC = 62,
    ZONEMD = 63,
    SVCB = 64,
    HTTPS = 65,
    DSYNC = 66,
    HHIT = 67,
    BRID = 68,
    SPF = 99,
    UINFO = 100,
    UID = 101,
    GID = 102,
    UNSPEC = 103,
    NID = 104,
    L32 = 105,
    L64 = 106,
    LP = 107,
    EUI48 = 108,
    EUI64 = 109,
    NXNAME = 128,
    TKEY = 249,
    TSIG = 250,
    IXFR = 251,
    AXFR = 252,
    MAILB = 253,
    MAILA = 254,
    ANY = 255,
    URI = 256,
    CAA = 257,
    AVC = 258,
    DOA = 259,
    AMTRELAY = 260,
    RESINFO = 261,
    WALLET = 262,
    CLA = 263,
    IPN = 264,
    TA = 32768,
    DLV = 32769,
}


#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Record {
    A {
        addr: Ipv4Addr,
    },
    AAAA {
        addr: Ipv6Addr,
    },
    NS {
        host: String,
    },
    CNAME {
        host: String,
    },
    SOA {
        mname: String,
        rname: String,
        serial: u32,
        refresh: u32,
        retry: u32,
        expire: u32,
        minimum: u32,
    },
    MX {
        preference: u16,
        exchange: String,
    },
    TXT {
        text: Vec<String>,
    },
    SRV {
        priority: u16,
        weight: u16,
        port: u16,
        target: String,
    },
    PTR {
        host: String,
    },
    CAA {
        flags: u8,
        tag: String,
        value: Vec<u8>,
    },
    DS {
        key_tag: u16,
        algorithm: u8,
        digest_type: u8,
        digest: Vec<u8>,
    },
    DNSKEY {
        flags: u16,
        protocol: u8,
        algorithm: u8,
        public_key: Vec<u8>,
    },
    RRSIG {
        type_covered: u16,
        algorithm: u8,
        labels: u8,
        original_ttl: u32,
        signature_expiration: u32,
        signature_inception: u32,
        key_tag: u16,
        signer_name: String,
        signature: Vec<u8>,
    },
    Unknown {
        typ: u16,
        data: Vec<u8>,
    },
}

pub fn lookup_via_system(name: HostName) -> Result<Vec<IpAddr>> {
    todo!()
}

pub fn lookup_via_server(server: IpAddr) -> Result<Record> {
    todo!()
}

#[cfg(test)]
mod tests {
    use super::*;

}
