/*
 * 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 <axis2_listener_manager.h>
#include <axis2_const.h>
#include <axutil_hash.h>
#include <axis2_transport_receiver.h>

/**
 * keep information about the listener for a given transport
 */
typedef struct axis2_transport_listener_state
{
    int waiting_calls;

    axis2_transport_receiver_t *listener;

} axis2_transport_listener_state_t;

struct axis2_listener_manager
{

    /** hash map of listeners */
    axis2_transport_listener_state_t *listener_map[AXIS2_TRANSPORT_ENUM_MAX];
    axutil_thread_t *listener_thread[AXIS2_TRANSPORT_ENUM_MAX];

    /** configuration context */
    axis2_conf_ctx_t *conf_ctx;
};

typedef struct axis2_listener_manager_worker_func_args
{
    const axutil_env_t *env;
    axis2_listener_manager_t *listner_manager;
    axis2_transport_receiver_t *listener;
} axis2_listener_manager_worker_func_args_t;

void *AXIS2_THREAD_FUNC axis2_listener_manager_worker_func(
    axutil_thread_t * thd,
    void *data);

AXIS2_EXTERN axis2_listener_manager_t *AXIS2_CALL
axis2_listener_manager_create(
    const axutil_env_t * env)
{
    axis2_listener_manager_t *listener_manager = NULL;
    int i = 0;

    AXIS2_ENV_CHECK(env, NULL);

    listener_manager = AXIS2_MALLOC(env->allocator, sizeof(axis2_listener_manager_t));

    if(!listener_manager)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create listener manager.");
        return NULL;
    }

    listener_manager->conf_ctx = NULL;

    for(i = 0; i < AXIS2_TRANSPORT_ENUM_MAX; i++)
    {
        listener_manager->listener_map[i] = NULL;
        listener_manager->listener_thread[i] = NULL;
    }

    return listener_manager;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_listener_manager_make_sure_started(
    axis2_listener_manager_t * listener_manager,
    const axutil_env_t * env,
    const AXIS2_TRANSPORT_ENUMS transport,
    axis2_conf_ctx_t * conf_ctx)
{
    axis2_transport_listener_state_t *tl_state = NULL;

    AXIS2_PARAM_CHECK(env->error, conf_ctx, AXIS2_FAILURE);

    if(listener_manager->conf_ctx)
    {
        if(conf_ctx != listener_manager->conf_ctx)
        {
            AXIS2_ERROR_SET(env->error, AXIS2_ERROR_CLIENT_SIDE_SUPPORT_ONLY_ONE_CONF_CTX,
                AXIS2_FAILURE);
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "Only one configuration context is supported at client side.");
            return AXIS2_FAILURE;
        }
    }
    else
    {
        listener_manager->conf_ctx = conf_ctx;
    }

    tl_state = listener_manager->listener_map[transport];

    if(!tl_state)
    {
        /*means this transport not yet started, start the transport */
        axis2_transport_in_desc_t *transport_in = NULL;
        axis2_conf_t *conf = NULL;
        axis2_transport_receiver_t *listener = NULL;

        conf = axis2_conf_ctx_get_conf(conf_ctx, env);
        if(conf)
        {
            transport_in = axis2_conf_get_transport_in(conf, env, transport);
            if(transport_in)
            {
                listener = axis2_transport_in_desc_get_recv(transport_in, env);
                if(listener)
                {
#ifdef AXIS2_SVR_MULTI_THREADED
                    axutil_thread_t *worker_thread = NULL;
#endif
                    axis2_listener_manager_worker_func_args_t *arg_list = NULL;
                    arg_list = AXIS2_MALLOC(env->allocator,
                        sizeof(axis2_listener_manager_worker_func_args_t));
                    if(!arg_list)
                    {
                        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "No memory. Cannot create listener manager worker function arguments.");
                        return AXIS2_FAILURE;
                    }
                    arg_list->env = env;
                    arg_list->listner_manager = listener_manager;
                    arg_list->listener = listener;
#ifdef AXIS2_SVR_MULTI_THREADED
                    if (env->thread_pool)
                    {
                        worker_thread =
                        axutil_thread_pool_get_thread(env->thread_pool,
                            axis2_listener_manager_worker_func,
                            (void *) arg_list);
                        if (!worker_thread)
                        {
                            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "Thread creation failed"
                                "Invoke non blocking failed");
                        }
                        else
                        {
                            /*axutil_thread_pool_thread_detach(env->thread_pool,
                                worker_thread);*/
                            /* we should not detach this, because, in the dual channel case
                            we should be able to terminate the thread before deleting the listener */
                        }
                    }
                    else
                    {
                        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "Thread pool not set in environment."
                            " Cannot invoke call non blocking");
                    }
#else
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Threading not enabled."
                        " Cannot start separate listener");
                    return AXIS2_FAILURE;
#endif

                    tl_state = AXIS2_MALLOC(env->allocator,
                        sizeof(axis2_transport_listener_state_t));

                    if(!tl_state)
                    {
                        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
                        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "No memory. Cannot create transport listener state.");
                    }
                    else
                    {
                        tl_state->listener = listener;
                        tl_state->waiting_calls = 0;
                        listener_manager->listener_map[transport] = tl_state;
#ifdef AXIS2_SVR_MULTI_THREADED
                        listener_manager->listener_thread[transport] = worker_thread;
#endif
                    }
                }
            }
        }
    }

    if(tl_state)
    {
        tl_state->waiting_calls++;
        return AXIS2_SUCCESS;
    }
    else
        return AXIS2_FAILURE;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axis2_listener_manager_stop(
    axis2_listener_manager_t * listener_manager,
    const axutil_env_t * env,
    const AXIS2_TRANSPORT_ENUMS transport)
{
    axis2_transport_listener_state_t *tl_state = NULL;
    axis2_status_t status = AXIS2_FAILURE;
    axutil_thread_t *listener_thread = NULL;

    tl_state = listener_manager->listener_map[transport];
    listener_thread = listener_manager->listener_thread[transport];

    if(tl_state)
    {
        tl_state->waiting_calls--;
        if(tl_state->waiting_calls == 0)
        {
            status = axis2_transport_receiver_stop(tl_state->listener, env);
            if(status == AXIS2_SUCCESS)
                listener_manager->listener_map[transport] = NULL;
        }
    }

    if(listener_thread)
    {
        axutil_thread_pool_exit_thread(env->thread_pool, listener_thread);
        listener_manager->listener_thread[transport] = NULL;
    }

    return status;
}

AXIS2_EXTERN axis2_endpoint_ref_t *AXIS2_CALL
axis2_listener_manager_get_reply_to_epr(
    const axis2_listener_manager_t * listener_manager,
    const axutil_env_t * env,
    const axis2_char_t * svc_name,
    const AXIS2_TRANSPORT_ENUMS transport)
{
    axis2_transport_listener_state_t *tl_state = NULL;

    tl_state = listener_manager->listener_map[transport];
    if(tl_state)
    {
        return axis2_transport_receiver_get_reply_to_epr(tl_state->listener, env, svc_name);
    }
    return NULL;
}

AXIS2_EXTERN void AXIS2_CALL
axis2_listener_manager_free(
    axis2_listener_manager_t * listener_manager,
    const axutil_env_t * env)
{
    int i = 0;

    for(i = 0; i < AXIS2_TRANSPORT_ENUM_MAX; i++)
    {
        if(listener_manager->listener_map[i])
            AXIS2_FREE(env->allocator, listener_manager->listener_map[i]);
    }

    AXIS2_FREE(env->allocator, listener_manager);
}

AXIS2_EXTERN axis2_conf_ctx_t *AXIS2_CALL
axis2_listener_manager_get_conf_ctx(
    const axis2_listener_manager_t * listener_manager,
    const axutil_env_t * env)
{
    return listener_manager->conf_ctx;
}

void *AXIS2_THREAD_FUNC
axis2_listener_manager_worker_func(
    axutil_thread_t * thd,
    void *data)
{
    axis2_listener_manager_worker_func_args_t *args_list = NULL;
    const axutil_env_t *th_env = NULL;

    args_list = (axis2_listener_manager_worker_func_args_t *)data;
    if(!args_list)
        return NULL;

    th_env = axutil_init_thread_env(args_list->env);
    /* Start the protocol server. For examlle if protocol is http axis2_http_server_start function
     * of the axis2_http_receiver is called.
     */
    if(args_list->listener)
    {
        axis2_transport_receiver_start(args_list->listener, th_env);
    }
    return NULL;
}
