/*
 *
 * 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 "contexts.hpp"

#include "msg.hpp"
#include "proton_bits.hpp"

#include "proton/connection_options.hpp"
#include "proton/error.hpp"
#include "proton/reconnect_options.hpp"

#include <proton/connection.h>
#include <proton/object.h>
#include <proton/link.h>
#include <proton/listener.h>
#include <proton/message.h>
#include <proton/session.h>

#include <typeinfo>

namespace proton {

namespace {
void cpp_context_finalize(void* v) { reinterpret_cast<context*>(v)->~context(); }
#define CID_cpp_context CID_pn_object
#define cpp_context_initialize NULL
#define cpp_context_hashcode NULL
#define cpp_context_compare NULL
#define cpp_context_inspect NULL
pn_class_t cpp_context_class = PN_CLASS(cpp_context);

// Handles
PN_HANDLE(CONNECTION_CONTEXT)
PN_HANDLE(LISTENER_CONTEXT)
PN_HANDLE(SESSION_CONTEXT)
PN_HANDLE(LINK_CONTEXT)

template <class T>
T* get_context(pn_record_t* record, pn_handle_t handle) {
    return reinterpret_cast<T*>(pn_record_get(record, handle));
}

}

context::~context() {}

void *context::alloc(size_t n) { return pn_object_new(&cpp_context_class, n); }

pn_class_t* context::pn_class() { return &cpp_context_class; }

connection_context::connection_context() :
    container(0), default_session(0), link_gen(0), handler(0), listener_context_(0)
{}

reconnect_context::reconnect_context(const reconnect_options& ro) :
    reconnect_options_(new reconnect_options(ro)), retries_(0), current_url_(-1), reconnected_(false)
{}

listener_context::listener_context() : listen_handler_(0) {}

connection_context& connection_context::get(pn_connection_t *c) {
    return ref<connection_context>(id(pn_connection_attachments(c), CONNECTION_CONTEXT));
}

listener_context& listener_context::get(pn_listener_t* l) {
    return ref<listener_context>(id(pn_listener_attachments(l), LISTENER_CONTEXT));
}

link_context& link_context::get(pn_link_t* l) {
    return ref<link_context>(id(pn_link_attachments(l), LINK_CONTEXT));
}

session_context& session_context::get(pn_session_t* s) {
    return ref<session_context>(id(pn_session_attachments(s), SESSION_CONTEXT));
}

}
