/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless requied by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#ifndef DNS_RESPONDER_H
#define DNS_RESPONDER_H

#include <arpa/nameser.h>

#include <atomic>
#include <mutex>
#include <string>
#include <thread>
#include <unordered_map>
#include <vector>

// TODO(imaipi): This doesn't belong here.
#if defined(__clang__) && (!defined(SWIG))
#define THREAD_ANNOTATION_ATTRIBUTE__(x)   __attribute__((x))
#else
#define THREAD_ANNOTATION_ATTRIBUTE__(x)   // no-op
#endif
#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))

namespace test {

struct DNSHeader;
struct DNSQuestion;
struct DNSRecord;

/*
 * Simple DNS responder, which replies to queries with the registered response
 * for that type. Class is assumed to be IN. If no response is registered, the
 * default error response code is returned.
 */
class DNSResponder {
public:
    DNSResponder(const char* listen_address, const char* listen_service,
                 int poll_timeout_ms, uint16_t error_rcode);
    ~DNSResponder();
    void addMapping(const char* name, ns_type type, const char* addr);
    void removeMapping(const char* name, ns_type type);
    bool running() const;
    bool startServer();
    bool stopServer();
    std::vector<std::pair<std::string, ns_type>> queries() const;
    void clearQueries();

private:
    // Key used for accessing mappings.
    struct QueryKey {
        std::string name;
        unsigned type;
        QueryKey(std::string n, unsigned t) : name(n), type(t) {}
        bool operator == (const QueryKey& o) const {
            return name == o.name && type == o.type;
        }
        bool operator < (const QueryKey& o) const {
            if (name < o.name) return true;
            if (name > o.name) return false;
            return type < o.type;
        }
    };

    struct QueryKeyHash {
        size_t operator() (const QueryKey& key) const {
            return std::hash<std::string>()(key.name) +
                   static_cast<size_t>(key.type);
        }
    };

    // DNS request handler.
    void requestHandler();

    // Parses and generates a response message for incoming DNS requests.
    // Returns false on parsing errors.
    bool handleDNSRequest(const char* buffer, ssize_t buffer_len,
                          char* response, size_t* response_len) const;

    bool addAnswerRecords(const DNSQuestion& question,
                          std::vector<DNSRecord>* answers) const;

    bool generateErrorResponse(DNSHeader* header, ns_rcode rcode,
                               char* response, size_t* response_len) const;
    bool makeErrorResponse(DNSHeader* header, ns_rcode rcode, char* response,
                           size_t* response_len) const;


    // Address and service to listen on, currently limited to UDP.
    const std::string listen_address_;
    const std::string listen_service_;
    // epoll_wait() timeout in ms.
    const int poll_timeout_ms_;
    // Error code to return for requests for an unknown name.
    const uint16_t error_rcode_;

    // Mappings from (name, type) to registered response and the
    // mutex protecting them.
    std::unordered_map<QueryKey, std::string, QueryKeyHash> mappings_
        GUARDED_BY(mappings_mutex_);
    // TODO(imaipi): enable GUARDED_BY(mappings_mutex_);
    std::mutex mappings_mutex_;
    // Query names received so far and the corresponding mutex.
    mutable std::vector<std::pair<std::string, ns_type>> queries_
        GUARDED_BY(queries_mutex_);
    mutable std::mutex queries_mutex_;
    // Socket on which the server is listening.
    int socket_;
    // File descriptor for epoll.
    int epoll_fd_;
    // Signal for request handler termination.
    std::atomic<bool> terminate_ GUARDED_BY(update_mutex_);
    // Thread for handling incoming threads.
    std::thread handler_thread_ GUARDED_BY(update_mutex_);
    std::mutex update_mutex_;
};

}  // namespace test

#endif  // DNS_RESPONDER_H
