require "socket"

module AsyncDNS
  abstract struct RR
    property name : String
    property dns_class : DNSClass
    property type : RRType
    property ttl : UInt32

    def initialize(@name : String, @dns_class : DNSClass, @type : RRType,
                   @ttl : UInt32)
    end

    struct A < RR
      property address : Socket::IPAddress

      def initialize(name : String, @address : Socket::IPAddress, ttl : UInt32)
        super(name, :in, :a, ttl)
      end
    end

    struct AAAA < RR
      property address : Socket::IPAddress

      def initialize(name : String, @address : Socket::IPAddress, ttl : UInt32)
        super(name, :in, :aaaa, ttl)
      end
    end

    struct CNAME < RR
      property alias : String

      def initialize(name : String, @alias : String, ttl : UInt32)
        super(name, :in, :cname, ttl)
      end
    end

    struct HINFO < RR
      property cpu : String
      property os : String

      def initialize(name : String, @cpu : String, @os : String, ttl : UInt32)
        super(name, :in, :hinfo, ttl)
      end
    end

    struct MX < RR
      property preference : UInt16
      property mx : String

      def initialize(name : String, @preference : UInt16, @mx : String,
                     ttl : UInt32)
        super(name, :in, :mx, ttl)
      end
    end

    struct NS < RR
      property authority : String

      def initialize(name : String, @authority : String, ttl : UInt32)
        super(name, :in, :ns, ttl)
      end
    end

    struct PTR < RR
      property domain : String

      def initialize(name : String, @domain : String, ttl : UInt32)
        super(name, :in, :ptr, ttl)
      end
    end

    struct RP < RR
      property mailbox : String
      property domain : String

      def initialize(name : String, @mailbox : String, @domain : String,
                     ttl : UInt32)
        super(name, :in, :rp, ttl)
      end
    end

    struct SOA < RR
      property primary_ns : String
      property responsible : String
      property serial : UInt32
      property refresh : UInt32
      property retry : UInt32
      property expire : UInt32
      property min_ttl : UInt32

      def initialize(name : String, @primary_ns : String, @responsible : String,
                     @serial : UInt32, @refresh : UInt32, @retry : UInt32,
                     @expire : UInt32, @min_ttl : UInt32, ttl : UInt32)
        super(name, :in, :soa, ttl)
      end
    end

    struct SRV < RR
      property prio : UInt16
      property weight : UInt16
      property target : String
      property port : UInt16

      def initialize(name : String, @prio : UInt16, @weight : UInt16,
                     @target : String, @port : UInt16, ttl : UInt32)
        super(name, :in, :srv, ttl)
      end
    end

    struct TXT < RR
      property text : Array(String)

      def initialize(name : String, @text : Array(String), ttl : UInt32)
        super(name, :in, :txt)
      end
    end
  end
end
