/*
 * 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>

#include <android-base/thread_annotations.h>

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,
                 double response_probability);
    ~DNSResponder();
    void addMapping(const char* name, ns_type type, const char* addr);
    void removeMapping(const char* name, ns_type type);
    void setResponseProbability(double response_probability);
    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_;
    // Probability that a valid response is being sent instead of being sent
    // instead of returning error_rcode_.
    std::atomic<double> response_probability_;

    // 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
