#include "lookup.h"
#include "stdio_impl.h"
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <poll.h>
#include <stdint.h>
#include <string.h>
#include <sys/socket.h>
#include <time.h>
#include <unistd.h>

static unsigned long mtime(void) {
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);
    return (unsigned long)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
}

int __res_msend_rc(int nqueries, const unsigned char* const* queries, const int* qlens,
                   unsigned char* const* answers, int* alens, int asize,
                   const struct resolvconf* conf) {
    int fd;
    int timeout, attempts, retry_interval, servfail_retry = 0;
    union {
        struct sockaddr_in sin;
        struct sockaddr_in6 sin6;
    } sa = {}, ns[MAXNS] = {};
    socklen_t sl = sizeof sa.sin;
    int nns = 0;
    int family = AF_INET;
    int rlen;
    int next;
    int i, j;
    struct pollfd pfd;
    unsigned long t0, t1, t2;

    timeout = 1000 * conf->timeout;
    attempts = conf->attempts;

    for (nns = 0; nns < conf->nns; nns++) {
        const struct address* iplit = &conf->ns[nns];
        if (iplit->family == AF_INET) {
            memcpy(&ns[nns].sin.sin_addr, iplit->addr, 4);
            ns[nns].sin.sin_port = htons(53);
            ns[nns].sin.sin_family = AF_INET;
        } else {
            sl = sizeof sa.sin6;
            memcpy(&ns[nns].sin6.sin6_addr, iplit->addr, 16);
            ns[nns].sin6.sin6_port = htons(53);
            ns[nns].sin6.sin6_scope_id = iplit->scopeid;
            ns[nns].sin6.sin6_family = family = AF_INET6;
        }
    }

    /* Get local address and open/bind a socket */
    sa.sin.sin_family = family;
    fd = socket(family, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);

    /* Handle case where system lacks IPv6 support */
    if (fd < 0 && family == AF_INET6 && errno == EAFNOSUPPORT) {
        fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
        family = AF_INET;
    }
    if (fd < 0 || bind(fd, (void*)&sa, sl) < 0)
        return -1;

    /* Past this point, there are no errors. Each individual query will
     * yield either no reply (indicated by zero length) or an answer
     * packet which is up to the caller to interpret. */

    /* Convert any IPv4 addresses in a mixed environment to v4-mapped */
    if (family == AF_INET6) {
        setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0);
        for (i = 0; i < nns; i++) {
            if (ns[i].sin.sin_family != AF_INET)
                continue;
            memcpy(ns[i].sin6.sin6_addr.s6_addr + 12, &ns[i].sin.sin_addr, 4);
            memcpy(ns[i].sin6.sin6_addr.s6_addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
            ns[i].sin6.sin6_family = AF_INET6;
            ns[i].sin6.sin6_flowinfo = 0;
            ns[i].sin6.sin6_scope_id = 0;
        }
    }

    memset(alens, 0, sizeof *alens * nqueries);

    pfd.fd = fd;
    pfd.events = POLLIN;
    retry_interval = timeout / attempts;
    next = 0;
    t0 = t2 = mtime();
    t1 = t2 - retry_interval;

    for (; t2 - t0 < timeout; t2 = mtime()) {
        if (t2 - t1 >= retry_interval) {
            /* Query all configured namservers in parallel */
            for (i = 0; i < nqueries; i++)
                if (!alens[i])
                    for (j = 0; j < nns; j++)
                        sendto(fd, queries[i], qlens[i], 0, (void*)&ns[j], sl);
            t1 = t2;
            servfail_retry = 2 * nqueries;
        }

        /* Wait for a response, or until time to retry */
        if (poll(&pfd, 1, t1 + retry_interval - t2) <= 0)
            continue;

        while ((rlen = recvfrom(fd, answers[next], asize, 0, (void*)&sa, (socklen_t[1]){sl})) >=
               0) {

            /* Ignore non-identifiable packets */
            if (rlen < 4)
                continue;

            /* Ignore replies from addresses we didn't send to */
            for (j = 0; j < nns && memcmp(ns + j, &sa, sl); j++)
                ;
            if (j == nns)
                continue;

            /* Find which query this answer goes with, if any */
            for (i = next; i < nqueries &&
                           (answers[next][0] != queries[i][0] || answers[next][1] != queries[i][1]);
                 i++)
                ;
            if (i == nqueries)
                continue;
            if (alens[i])
                continue;

            /* Only accept positive or negative responses;
             * retry immediately on server failure, and ignore
             * all other codes such as refusal. */
            switch (answers[next][3] & 15) {
            case 0:
            case 3:
                break;
            case 2:
                if (servfail_retry && servfail_retry--)
                    sendto(fd, queries[i], qlens[i], 0, (void*)&ns[j], sl);
            default:
                continue;
            }

            /* Store answer in the right slot, or update next
             * available temp slot if it's already in place. */
            alens[i] = rlen;
            if (i == next)
                for (; next < nqueries && alens[next]; next++)
                    ;
            else
                memcpy(answers[i], answers[next], rlen);

            if (next == nqueries)
                goto out;
        }
    }
out:

    return 0;
}

int __res_msend(int nqueries, const unsigned char* const* queries, const int* qlens,
                unsigned char* const* answers, int* alens, int asize) {
    struct resolvconf conf;
    if (__get_resolv_conf(&conf, 0, 0) < 0)
        return -1;
    return __res_msend_rc(nqueries, queries, qlens, answers, alens, asize, &conf);
}
