/*
 * Copyright (C) 2009 - 2010 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */
/* $Id$ */

#pragma once

#include <commontypes.h>
#include <platform.h>
#include <serverexchange/DNSQueryDef.h>

#include <arpa/nameser.h>
#if defined(PLATFORM_MAC)
#include <machine/endian.h>
#include <arpa/nameser_compat.h>
#endif

typedef HEADER DNS_QUERY_HEADER;

namespace NS_DM_Client
{

    namespace NS_DNS_Query
    {
        typedef int ret_code_t;
        typedef int opcode_t;

        class Header
        {
        public:
            Header(const DNS_QUERY_HEADER& hdr);

            unsigned id() const;
            bool isResponse() const;
//            opcode_t opcode() const;
            bool isAuthoritative() const;
            bool isTruncated() const;
            bool isRecursionDesired() const;
            bool isRecursionAvailable() const;
            bool dataAuthentic() const;
            bool isCheckDisabled() const;
//            ret_code_t rcode() const;
            unsigned questionCount() const;
            unsigned answerCount() const;
            unsigned nsCount() const;
            unsigned additionalCount() const;

            unsigned size() const;

        private:
            unsigned m_id;          /// Query ID
            bool m_resp;            /// false if query, true if response
            opcode_t m_opcode;      /// Operation code
            bool m_authoritative;   /// Whether the answer is authoritative
            bool m_truncated;       /// Whether the answer was truncated
            bool m_rd;              /// Recursion Desired
            bool m_ra;              /// Recursion Available
            bool m_ad;
            bool m_cd;
            ret_code_t m_rcode;     /// Response Code
            unsigned m_qdcount;
            unsigned m_ancount;
            unsigned m_nscount;
            unsigned m_arcount;

        };


        class DnsQuestion {
        public:
            DnsQuestion();

            bool Set(const unsigned char* data, size_t max_len,
                const unsigned char* msgstart, const unsigned char* msgend);

            const String& GetName() const;
            EnumType GetType() const;
            EnumClass GetClass() const;

            size_t GetLength() const;

        protected:
            String m_qname;
            EnumType m_qtype;
            EnumClass m_qclass;
            size_t m_full_length;

        };


        class DnsSrvRr
        {
        public:
            DnsSrvRr();

            bool Set(const unsigned char* data, size_t max_len,
            const unsigned char* msgstart, const unsigned char* msgend);

            const String& name() const;
            EnumType type() const;
            EnumClass getClass() const;
            uint32_t ttl() const;
            uint16_t length() const;
//            const uint8_t* data() const;

            const String& target() const;
            uint16_t priority() const;
            uint16_t weight() const;
            uint16_t port() const;

            size_t  getLength() const;

        protected:
            String m_name;
            EnumType m_type;
            EnumClass m_class;
            uint32_t m_ttl;
            uint16_t m_length;
//            uint8_t* m_data;
            const unsigned char* m_data_ptr;
            size_t m_full_length;

            uint16_t m_priority;
            uint16_t m_weight;
            uint16_t m_port;
            String m_target;
        };
    }

}

