/*
 *
 * 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/handlers.h>
#include <proton/selector.h>
#include <proton/transport.h>
#include <assert.h>

static const char pni_selector_handle = 0;

#define PN_SELECTOR ((pn_handle_t) &pni_selector_handle)

void pni_handle_quiesced(pn_reactor_t *reactor, pn_selector_t *selector) {
  // check if we are still quiesced, other handlers of
  // PN_REACTOR_QUIESCED could have produced more events to process
  if (!pn_reactor_quiesced(reactor)) { return; }
  pn_selector_select(selector, pn_reactor_get_timeout(reactor));
  pn_selectable_t *sel;
  int events;
  pn_reactor_mark(reactor);
  while ((sel = pn_selector_next(selector, &events))) {
    if (events & PN_READABLE) {
      pn_selectable_readable(sel);
    }
    if (events & PN_WRITABLE) {
      pn_selectable_writable(sel);
    }
    if (events & PN_EXPIRED) {
      pn_selectable_expired(sel);
    }
    if (events & PN_ERROR) {
      pn_selectable_error(sel);
    }
  }
  pn_reactor_yield(reactor);
}

void pni_handle_transport(pn_reactor_t *reactor, pn_event_t *event);
void pni_handle_open(pn_reactor_t *reactor, pn_event_t *event);
void pni_handle_bound(pn_reactor_t *reactor, pn_event_t *event);

static void pn_iodispatch(pn_iohandler_t *handler, pn_event_t *event, pn_event_type_t type) {
  pn_reactor_t *reactor = pn_event_reactor(event);
  pn_record_t *record = pn_reactor_attachments(reactor);
  pn_selector_t *selector = (pn_selector_t *) pn_record_get(record, PN_SELECTOR);
  if (!selector) {
    selector = pn_io_selector(pn_reactor_io(reactor));
    pn_record_def(record, PN_SELECTOR, PN_OBJECT);
    pn_record_set(record, PN_SELECTOR, selector);
    pn_decref(selector);
  }
  switch (type) {
  case PN_SELECTABLE_INIT:
    {
      pn_selectable_t *sel = (pn_selectable_t *) pn_event_context(event);
      pn_selector_add(selector, sel);
    }
    break;
  case PN_SELECTABLE_UPDATED:
    {
      pn_selectable_t *sel = (pn_selectable_t *) pn_event_context(event);
      pn_selector_update(selector, sel);
    }
    break;
  case PN_SELECTABLE_FINAL:
    {
      pn_selectable_t *sel = (pn_selectable_t *) pn_event_context(event);
      pn_selector_remove(selector, sel);
      pn_selectable_release(sel);
    }
    break;
  case PN_CONNECTION_LOCAL_OPEN:
    pni_handle_open(reactor, event);
    break;
  case PN_CONNECTION_BOUND:
    pni_handle_bound(reactor, event);
    break;
  case PN_TRANSPORT:
    pni_handle_transport(reactor, event);
    break;
  case PN_TRANSPORT_CLOSED:
    pn_transport_unbind(pn_event_transport(event));
    break;
  case PN_REACTOR_QUIESCED:
    pni_handle_quiesced(reactor, selector);
    break;
  default:
    break;
  }
}

pn_iohandler_t *pn_iohandler(void) {
  return pn_handler(pn_iodispatch);
}
