/*
    Copyright (c) 2012 Martin Sustrik  All rights reserved.
    Copyright (c) 2013 GoPivotal, Inc.  All rights reserved.
    Copyright 2016 Garrett D'Amore <garrett@damore.org>

    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 "../transport.h"

#include "ep.h"
#include "sock.h"

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

#include <string.h>

#define NN_EP_STATE_IDLE 1
#define NN_EP_STATE_ACTIVE 2
#define NN_EP_STATE_STOPPING 3

#define NN_EP_ACTION_STOPPED 1

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

int nn_ep_init (struct nn_ep *self, int src, struct nn_sock *sock, int eid,
    const struct nn_transport *transport, int bind, const char *addr)
{
    int rc;

    nn_fsm_init (&self->fsm, nn_ep_handler, nn_ep_shutdown,
        src, self, &sock->fsm);
    self->state = NN_EP_STATE_IDLE;

    self->sock = sock;
    self->eid = eid;
    self->last_errno = 0;
    nn_list_item_init (&self->item);
    memcpy (&self->options, &sock->ep_template, sizeof(struct nn_ep_options));

    /*  Store the textual form of the address. */
    nn_assert (strlen (addr) <= NN_SOCKADDR_MAX);
    strcpy (self->addr, addr);

    /*  Create transport-specific part of the endpoint. */
    if (bind)
        rc = transport->bind (self);
    else
        rc = transport->connect (self);

    /*  Endpoint creation failed. */
    if (rc < 0) {
        nn_list_item_term (&self->item);
        nn_fsm_term (&self->fsm);
        return rc;
    }

    return 0;
}

void nn_ep_term (struct nn_ep *self)
{
    nn_assert_state (self, NN_EP_STATE_IDLE);

    self->ops.destroy (self->tran);
    nn_list_item_term (&self->item);
    nn_fsm_term (&self->fsm);
}

void nn_ep_start (struct nn_ep *self)
{
    nn_fsm_start (&self->fsm);
}

void nn_ep_stop (struct nn_ep *self)
{
    nn_fsm_stop (&self->fsm);
}

void nn_ep_stopped (struct nn_ep *self)
{
    /*  TODO: Do the following in a more sane way. */
    self->fsm.stopped.fsm = &self->fsm;
    self->fsm.stopped.src = NN_FSM_ACTION;
    self->fsm.stopped.srcptr = NULL;
    self->fsm.stopped.type = NN_EP_ACTION_STOPPED;
    nn_ctx_raise (self->fsm.ctx, &self->fsm.stopped);
}

struct nn_ctx *nn_ep_getctx (struct nn_ep *self)
{
    return nn_sock_getctx (self->sock);
}

const char *nn_ep_getaddr (struct nn_ep *self)
{
    return self->addr;
}

void nn_ep_getopt (struct nn_ep *self, int level, int option,
    void *optval, size_t *optvallen)
{
    int rc;

    rc = nn_sock_getopt_inner (self->sock, level, option, optval, optvallen);
    errnum_assert (rc == 0, -rc);
}

int nn_ep_ispeer (struct nn_ep *self, int socktype)
{
    return nn_sock_ispeer (self->sock, socktype);
}


static void nn_ep_shutdown (struct nn_fsm *self, int src, int type,
    NN_UNUSED void *srcptr)
{
    struct nn_ep *ep;

    ep = nn_cont (self, struct nn_ep, fsm);

    if (nn_slow (src == NN_FSM_ACTION && type == NN_FSM_STOP)) {
        ep->ops.stop (ep->tran);
        ep->state = NN_EP_STATE_STOPPING;
        return;
    }
    if (nn_slow (ep->state == NN_EP_STATE_STOPPING)) {
        if (src != NN_FSM_ACTION || type != NN_EP_ACTION_STOPPED)
            return;
        ep->state = NN_EP_STATE_IDLE;
        nn_fsm_stopped (&ep->fsm, NN_EP_STOPPED);
        return;
    }

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


static void nn_ep_handler (struct nn_fsm *self, int src, int type,
    NN_UNUSED void *srcptr)
{
    struct nn_ep *ep;

    ep = nn_cont (self, struct nn_ep, fsm);

    switch (ep->state) {

/******************************************************************************/
/*  IDLE state.                                                               */
/******************************************************************************/
    case NN_EP_STATE_IDLE:
        switch (src) {

        case NN_FSM_ACTION:
            switch (type) {
            case NN_FSM_START:
                ep->state = NN_EP_STATE_ACTIVE;
                return;
            default:
                nn_fsm_bad_action (ep->state, src, type);
            }

        default:
            nn_fsm_bad_source (ep->state, src, type);
        }

/******************************************************************************/
/*  ACTIVE state.                                                             */
/*  We don't expect any events in this state. The only thing that can be done */
/*  is closing the endpoint.                                                  */
/******************************************************************************/
    case NN_EP_STATE_ACTIVE:
        nn_fsm_bad_source (ep->state, src, type);

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

void nn_ep_set_error(struct nn_ep *self, int errnum)
{
    if (self->last_errno == errnum)
        /*  Error is still there, no need to report it again  */
        return;
    if (self->last_errno == 0)
        nn_sock_stat_increment (self->sock, NN_STAT_CURRENT_EP_ERRORS, 1);
    self->last_errno = errnum;
    nn_sock_report_error (self->sock, self, errnum);
}

void nn_ep_clear_error (struct nn_ep *self)
{
    if (self->last_errno == 0)
        /*  Error is already clear, no need to report it  */
        return;
    nn_sock_stat_increment (self->sock, NN_STAT_CURRENT_EP_ERRORS, -1);
    self->last_errno = 0;
    nn_sock_report_error (self->sock, self, 0);
}

void nn_ep_stat_increment (struct nn_ep *self, int name, int increment)
{
    nn_sock_stat_increment (self->sock, name, increment);
}

int nn_ep_ispeer_ep (struct nn_ep *self, struct nn_ep *other)
{
    return nn_ep_ispeer (self, other->sock->socktype->protocol);
}

/*  Set up an ep for use by a transport.  Note that the core will already have
    done most of the initialization steps.  The tran is passed as the argument
    to the ops. */
void nn_ep_tran_setup (struct nn_ep *ep, const struct nn_ep_ops *ops,
    void *tran)
{
    ep->ops = *ops;
    ep->tran = tran;
}
