/*
    Copyright (c) 2012-2013 250bpm s.r.o.  All rights reserved.

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom
    the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included
    in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    IN THE SOFTWARE.
*/

#include "literal.h"

#include "../../utils/err.h"
#include "../../utils/cont.h"

#include <string.h>

#ifndef NN_HAVE_WINDOWS
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#endif

#define NN_DNS_STATE_IDLE 1
#define NN_DNS_STATE_DONE 2

/*  Private functions. */
static void nn_dns_handler (struct nn_fsm *self, int src, int type,
    void *srcptr);
static void nn_dns_shutdown (struct nn_fsm *self, int src, int type,
    void *srcptr);

void nn_dns_init (struct nn_dns *self, int src, struct nn_fsm *owner)
{
    nn_fsm_init (&self->fsm, nn_dns_handler, nn_dns_shutdown,
        src, self, owner);
    self->state = NN_DNS_STATE_IDLE;
    nn_fsm_event_init (&self->done);
}

void nn_dns_term (struct nn_dns *self)
{
    nn_assert (self->state == NN_DNS_STATE_IDLE);

    nn_fsm_event_term (&self->done);
    nn_fsm_term (&self->fsm);
}

int nn_dns_isidle (struct nn_dns *self)
{
    return nn_fsm_isidle (&self->fsm);
}

void nn_dns_start (struct nn_dns *self, const char *addr, size_t addrlen,
    int ipv4only, struct nn_dns_result *result)
{
    int rc;
    struct addrinfo query;
    struct addrinfo *reply;
    char hostname [NN_SOCKADDR_MAX];

    nn_assert (self->state == NN_DNS_STATE_IDLE);

    self->result = result;

    /*  Try to resolve the supplied string as a literal address. In this case,
        there's no DNS lookup involved. */
    rc = nn_literal_resolve (addr, addrlen, ipv4only, &self->result->addr,
        &self->result->addrlen);
    if (rc == 0) {
        self->result->error = 0;
        nn_fsm_start (&self->fsm);
        return;
    }
    errnum_assert (rc == -EINVAL, -rc);

    /*  The name is not a literal. Let's do an actual DNS lookup. */
    memset (&query, 0, sizeof (query));
    if (ipv4only)
        query.ai_family = AF_INET;
    else {
        query.ai_family = AF_INET6;
#ifdef AI_V4MAPPED
        query.ai_flags = AI_V4MAPPED;
#endif
    }
    nn_assert (sizeof (hostname) > addrlen);
    query.ai_socktype = SOCK_STREAM;
    memcpy (hostname, addr, addrlen);
    hostname [addrlen] = 0;

    /*  Perform the DNS lookup itself. */
    self->result->error = getaddrinfo (hostname, NULL, &query, &reply);
    if (self->result->error) {
        nn_fsm_start (&self->fsm);
        return;
    }

    /*  Check that exactly one address is returned and store it. */
    nn_assert (reply && !reply->ai_next);
    self->result->error = 0;
    memcpy (&self->result->addr, reply->ai_addr, reply->ai_addrlen);
    self->result->addrlen = reply->ai_addrlen;
    freeaddrinfo (reply);

    nn_fsm_start (&self->fsm);
}

void nn_dns_stop (struct nn_dns *self)
{
    nn_fsm_stop (&self->fsm);
}

static void nn_dns_shutdown (struct nn_fsm *self, int src, int type,
    void *srcptr)
{
    struct nn_dns *dns;

    dns = nn_cont (self, struct nn_dns, fsm);
    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {
        nn_fsm_stopped (&dns->fsm, NN_DNS_STOPPED);
        dns->state = NN_DNS_STATE_IDLE;
        return;
    }

    nn_fsm_bad_state(dns->state, src, type);
}

static void nn_dns_handler (struct nn_fsm *self, int src, int type,
    void *srcptr)
{
    struct nn_dns *dns;

    dns = nn_cont (self, struct nn_dns, fsm);

    switch (dns->state) {
/******************************************************************************/
/*  IDLE state.                                                               */
/******************************************************************************/
    case NN_DNS_STATE_IDLE:
        switch (src) {
        case NN_FSM_ACTION:
            switch (type) {
            case NN_FSM_START:
                nn_fsm_raise (&dns->fsm, &dns->done, NN_DNS_DONE);
                dns->state = NN_DNS_STATE_DONE;
                return;
            default:
                nn_fsm_bad_action (dns->state, src, type);
            }
        default:
            nn_fsm_bad_source (dns->state, src, type);
        }

/******************************************************************************/
/*  DONE state.                                                               */
/******************************************************************************/
    case NN_DNS_STATE_DONE:
        nn_fsm_bad_source (dns->state, src, type);

/******************************************************************************/
/*  Invalid state.                                                            */
/******************************************************************************/
    default:
        nn_fsm_bad_state (dns->state, src, type);
    }
}

