/*
 * 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.
 */
#ifdef AXIS2_SSL_ENABLED

#include <string.h>
#include <stdlib.h>
#include "ssl_stream.h"
#include "ssl_utils.h"

/**
 * @brief Stream struct impl
 *   Streaming mechanisms for SSL
 */
typedef struct ssl_stream_impl ssl_stream_impl_t;

struct ssl_stream_impl
{
    axutil_stream_t stream;
    axutil_stream_type_t stream_type;
    SSL *ssl;
    SSL_CTX *ctx;
    axis2_socket_t socket;
};

#define AXIS2_INTF_TO_IMPL(stream) ((ssl_stream_impl_t *)(stream))

axutil_stream_type_t AXIS2_CALL axis2_ssl_stream_get_type(
    axutil_stream_t * stream,
    const axutil_env_t * env);

int AXIS2_CALL axis2_ssl_stream_write(
    axutil_stream_t * stream,
    const axutil_env_t * env,
    const void *buffer,
    size_t count);

int AXIS2_CALL axis2_ssl_stream_read(
    axutil_stream_t * stream,
    const axutil_env_t * env,
    void *buffer,
    size_t count);

int AXIS2_CALL axis2_ssl_stream_skip(
    axutil_stream_t * stream,
    const axutil_env_t * env,
    int count);

int AXIS2_CALL axis2_ssl_stream_get_char(
    axutil_stream_t * stream,
    const axutil_env_t * env);

AXIS2_EXTERN axutil_stream_t *AXIS2_CALL
axutil_stream_create_ssl(
    const axutil_env_t * env,
    axis2_socket_t socket,
    axis2_char_t * server_cert,
    axis2_char_t * key_file,
    axis2_char_t * ssl_pp)
{
    ssl_stream_impl_t *stream_impl = NULL;

    stream_impl =
    (ssl_stream_impl_t *) AXIS2_MALLOC(env->allocator,
        sizeof(ssl_stream_impl_t));

    if (!stream_impl)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }
    memset ((void *)stream_impl, 0, sizeof (ssl_stream_impl_t));
    stream_impl->socket = socket;
    stream_impl->ctx = NULL;
    stream_impl->ssl = NULL;

    stream_impl->ctx = axis2_ssl_utils_initialize_ctx(env, server_cert,
        key_file, ssl_pp);
    if (!stream_impl->ctx)
    {
        axis2_ssl_stream_free((axutil_stream_t *) stream_impl, env);
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SSL_ENGINE, AXIS2_FAILURE);
        return NULL;
    }
    stream_impl->ssl = axis2_ssl_utils_initialize_ssl(env, stream_impl->ctx,
        stream_impl->socket);
    if (!stream_impl->ssl)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_SSL_ENGINE, AXIS2_FAILURE);
        return NULL;
    }
    stream_impl->stream_type = AXIS2_STREAM_MANAGED;

    axutil_stream_set_read(&(stream_impl->stream), env, axis2_ssl_stream_read);
    axutil_stream_set_write(&(stream_impl->stream), env,
        axis2_ssl_stream_write);
    axutil_stream_set_skip(&(stream_impl->stream), env, axis2_ssl_stream_skip);

    return &(stream_impl->stream);
}

void AXIS2_CALL
axis2_ssl_stream_free(
    void * streamv,
    const axutil_env_t * env)
{
    ssl_stream_impl_t *stream_impl = NULL;
    axutil_stream_t* stream = (axutil_stream_t*)streamv;
    if (stream)
    {
        stream_impl = AXIS2_INTF_TO_IMPL(stream);
        if (stream_impl)
        {
            axis2_ssl_utils_cleanup_ssl(env, stream_impl->ctx, stream_impl->ssl);
            AXIS2_FREE(env->allocator, stream_impl);
        }
    }

    return;
}

int AXIS2_CALL
axis2_ssl_stream_read(
    axutil_stream_t * stream,
    const axutil_env_t * env,
    void *buffer,
    size_t count)
{
    ssl_stream_impl_t *stream_impl = NULL;
    int read = -1;
    int len = -1;

    stream_impl = AXIS2_INTF_TO_IMPL(stream);

    SSL_set_mode(stream_impl->ssl, SSL_MODE_AUTO_RETRY);

    read = SSL_read(stream_impl->ssl, buffer, (int)count);
    /* We are sure that the difference lies within the int range */
    switch (SSL_get_error(stream_impl->ssl, read))
    {
        case SSL_ERROR_NONE:
        len = read;
        break;
        case SSL_ERROR_ZERO_RETURN:
        len = -1;
        break;
        case SSL_ERROR_SYSCALL:
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "SSL Error: Premature close");
        len = -1;
        break;
        default:
        len = -1;
        break;
    }
    return len;
}

int AXIS2_CALL
axis2_ssl_stream_write(
    axutil_stream_t * stream,
    const axutil_env_t * env,
    const void *buf,
    size_t count)
{
    ssl_stream_impl_t *stream_impl = NULL;
    int write = -1;

    AXIS2_PARAM_CHECK(env->error, buf, AXIS2_FAILURE);
    stream_impl = AXIS2_INTF_TO_IMPL(stream);
    write = SSL_write(stream_impl->ssl, buf, (int)count);
    /* We are sure that the difference lies within the int range */

    switch (SSL_get_error(stream_impl->ssl, write))
    {
        case SSL_ERROR_NONE:
        if ((int)count != write)
        /* We are sure that the difference lies within the int range */
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Incomplete SSL write!");
        break;
        default:
        return -1;
    }
    return write;
}

int AXIS2_CALL
axis2_ssl_stream_skip(
    axutil_stream_t * stream,
    const axutil_env_t * env,
    int count)
{
    ssl_stream_impl_t *stream_impl = NULL;
    axis2_char_t *tmp_buffer = NULL;
    int len = -1;
    stream_impl = AXIS2_INTF_TO_IMPL(stream);

    tmp_buffer = AXIS2_MALLOC(env->allocator, count * sizeof(axis2_char_t));
    if (tmp_buffer == NULL)
    {
        AXIS2_HANDLE_ERROR(env, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return -1;
    }
	SSL_set_mode(stream_impl->ssl, SSL_MODE_AUTO_RETRY);
    len = SSL_read(stream_impl->ssl, tmp_buffer, count);
    AXIS2_FREE(env->allocator, tmp_buffer);
    return len;

}

int AXIS2_CALL
axis2_ssl_stream_get_char(
    axutil_stream_t * stream,
    const axutil_env_t * env)
{
    int ret = -1;

    return ret;
}

axutil_stream_type_t AXIS2_CALL
axis2_ssl_stream_get_type(
    axutil_stream_t * stream,
    const axutil_env_t * env)
{
    return AXIS2_INTF_TO_IMPL(stream)->stream_type;
}

#endif

