/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 required 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.
 *
 */

#include <proton/error.h>
#include <proton/io.h>
#include "selectable.h"
#include <stdlib.h>
#include <assert.h>

pn_selectables_t *pn_selectables(void)
{
  return pn_iterator();
}

pn_selectable_t *pn_selectables_next(pn_selectables_t *selectables)
{
  return (pn_selectable_t *) pn_iterator_next(selectables);
}

void pn_selectables_free(pn_selectables_t *selectables)
{
  pn_free(selectables);
}

struct pn_selectable_t {
  pn_socket_t fd;
  int index;
  pn_record_t *attachments;
  void (*readable)(pn_selectable_t *);
  void (*writable)(pn_selectable_t *);
  void (*error)(pn_selectable_t *);
  void (*expired)(pn_selectable_t *);
  void (*release) (pn_selectable_t *);
  void (*finalize)(pn_selectable_t *);
  pn_collector_t *collector;
  pn_timestamp_t deadline;
  bool reading;
  bool writing;
  bool registered;
  bool terminal;
};

void pn_selectable_initialize(pn_selectable_t *sel)
{
  sel->fd = PN_INVALID_SOCKET;
  sel->index = -1;
  sel->attachments = pn_record();
  sel->readable = NULL;
  sel->writable = NULL;
  sel->error = NULL;
  sel->expired = NULL;
  sel->release = NULL;
  sel->finalize = NULL;
  sel->collector = NULL;
  sel->deadline = 0;
  sel->reading = false;
  sel->writing = false;
  sel->registered = false;
  sel->terminal = false;
}

void pn_selectable_finalize(pn_selectable_t *sel)
{
  if (sel->finalize) {
    sel->finalize(sel);
  }
  pn_decref(sel->attachments);
  pn_decref(sel->collector);
}

#define pn_selectable_hashcode NULL
#define pn_selectable_inspect NULL
#define pn_selectable_compare NULL

PN_CLASSDEF(pn_selectable)

pn_selectable_t *pn_selectable(void)
{
  return pn_selectable_new();
}

bool pn_selectable_is_reading(pn_selectable_t *sel) {
  assert(sel);
  return sel->reading;
}

void pn_selectable_set_reading(pn_selectable_t *sel, bool reading) {
  assert(sel);
  sel->reading = reading;
}

bool pn_selectable_is_writing(pn_selectable_t *sel) {
  assert(sel);
  return sel->writing;
}

void pn_selectable_set_writing(pn_selectable_t *sel, bool writing) {
  assert(sel);
  sel->writing = writing;
}

pn_timestamp_t pn_selectable_get_deadline(pn_selectable_t *sel) {
  assert(sel);
  return sel->deadline;
}

void pn_selectable_set_deadline(pn_selectable_t *sel, pn_timestamp_t deadline) {
  assert(sel);
  sel->deadline = deadline;
}

void pn_selectable_on_readable(pn_selectable_t *sel, void (*readable)(pn_selectable_t *)) {
  assert(sel);
  sel->readable = readable;
}

void pn_selectable_on_writable(pn_selectable_t *sel, void (*writable)(pn_selectable_t *)) {
  assert(sel);
  sel->writable = writable;
}

void pn_selectable_on_error(pn_selectable_t *sel, void (*error)(pn_selectable_t *)) {
  assert(sel);
  sel->error = error;
}

void pn_selectable_on_expired(pn_selectable_t *sel, void (*expired)(pn_selectable_t *)) {
  assert(sel);
  sel->expired = expired;
}

void pn_selectable_on_release(pn_selectable_t *sel, void (*release)(pn_selectable_t *)) {
  assert(sel);
  sel->release = release;
}

void pn_selectable_on_finalize(pn_selectable_t *sel, void (*finalize)(pn_selectable_t *)) {
  assert(sel);
  sel->finalize = finalize;
}

pn_record_t *pn_selectable_attachments(pn_selectable_t *sel) {
  return sel->attachments;
}

void *pni_selectable_get_context(pn_selectable_t *selectable)
{
  assert(selectable);
  return pn_record_get(selectable->attachments, PN_LEGCTX);
}

void pni_selectable_set_context(pn_selectable_t *selectable, void *context)
{
  assert(selectable);
  pn_record_set(selectable->attachments, PN_LEGCTX, context);
}

int pni_selectable_get_index(pn_selectable_t *selectable)
{
  assert(selectable);
  return selectable->index;
}

void pni_selectable_set_index(pn_selectable_t *selectable, int index)
{
  assert(selectable);
  selectable->index = index;
}

pn_socket_t pn_selectable_get_fd(pn_selectable_t *selectable)
{
  assert(selectable);
  return selectable->fd;
}

void pn_selectable_set_fd(pn_selectable_t *selectable, pn_socket_t fd)
{
  assert(selectable);
  selectable->fd = fd;
}

void pn_selectable_readable(pn_selectable_t *selectable)
{
  assert(selectable);
  if (selectable->readable) {
    selectable->readable(selectable);
  }
}

void pn_selectable_writable(pn_selectable_t *selectable)
{
  assert(selectable);
  if (selectable->writable) {
    selectable->writable(selectable);
  }
}

void pn_selectable_error(pn_selectable_t *selectable)
{
  assert(selectable);
  if (selectable->error) {
    selectable->error(selectable);
  }
}

void pn_selectable_expired(pn_selectable_t *selectable)
{
  assert(selectable);
  if (selectable->expired) {
    selectable->expired(selectable);
  }
}

bool pn_selectable_is_registered(pn_selectable_t *selectable)
{
  assert(selectable);
  return selectable->registered;
}

void pn_selectable_set_registered(pn_selectable_t *selectable, bool registered)
{
  assert(selectable);
  selectable->registered = registered;
}

bool pn_selectable_is_terminal(pn_selectable_t *selectable)
{
  assert(selectable);
  return selectable->terminal;
}

void pn_selectable_terminate(pn_selectable_t *selectable)
{
  assert(selectable);
  selectable->terminal = true;
}

void pn_selectable_release(pn_selectable_t *selectable)
{
  assert(selectable);
  if (selectable->release) {
    selectable->release(selectable);
  }
}

void pn_selectable_free(pn_selectable_t *selectable)
{
  pn_decref(selectable);
}

static void pni_readable(pn_selectable_t *selectable) {
  pn_collector_put(selectable->collector, PN_OBJECT, selectable, PN_SELECTABLE_READABLE);
}

static void pni_writable(pn_selectable_t *selectable) {
  pn_collector_put(selectable->collector, PN_OBJECT, selectable, PN_SELECTABLE_WRITABLE);
}

static void pni_error(pn_selectable_t *selectable) {
  pn_collector_put(selectable->collector, PN_OBJECT, selectable, PN_SELECTABLE_ERROR);
}

static void pni_expired(pn_selectable_t *selectable) {
  pn_collector_put(selectable->collector, PN_OBJECT, selectable, PN_SELECTABLE_EXPIRED);
}

void pn_selectable_collect(pn_selectable_t *selectable, pn_collector_t *collector) {
  assert(selectable);
  pn_decref(selectable->collector);
  selectable->collector = collector;
  pn_incref(selectable->collector);

  if (collector) {
    pn_selectable_on_readable(selectable, pni_readable);
    pn_selectable_on_writable(selectable, pni_writable);
    pn_selectable_on_error(selectable, pni_error);
    pn_selectable_on_expired(selectable, pni_expired);
  }
}
