/*
 * 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 <string.h>
#include <stdlib.h>
#include "axis2_iis_stream.h"
#include <httpext.h>

/**
 * @brief Stream struct impl
 * Streaming mechanisms for iis web server
 */

typedef struct iis_stream_impl
{
    axutil_stream_t stream;
    axutil_stream_type_t stream_type;
    LPEXTENSION_CONTROL_BLOCK lpECB;
    unsigned int cur_pos;
    void *cur_position;
} iis_stream_impl_t;

#define AXIS2_INTF_TO_IMPL(stream) ((iis_stream_impl_t *)(stream))

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

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

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

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

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

axutil_stream_t *AXIS2_CALL
axutil_stream_create_iis(
    const axutil_env_t * env,
    LPEXTENSION_CONTROL_BLOCK lpECB)
{
    iis_stream_impl_t *stream_impl = NULL;
    AXIS2_ENV_CHECK(env, NULL);
    AXIS2_PARAM_CHECK(env->error, lpECB, NULL);

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

    if(!stream_impl)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
    }
    stream_impl->cur_pos = 0;
    stream_impl->cur_position = NULL;
    stream_impl->lpECB = lpECB;
    stream_impl->stream_type = AXIS2_STREAM_MANAGED;

    axutil_stream_set_read(&(stream_impl->stream), env, iis_stream_read);
    axutil_stream_set_write(&(stream_impl->stream), env, iis_stream_write);
    axutil_stream_set_skip(&(stream_impl->stream), env, iis_stream_skip);

    return &(stream_impl->stream);
}

int AXIS2_CALL
iis_stream_read(
    axutil_stream_t * stream,
    const axutil_env_t * env,
    void *buffer,
    size_t count)
{
    void *temp_buff = NULL;
    unsigned int data_to_read = 0;
    DWORD ret_val = TRUE;
    DWORD read_bytes = (DWORD)count;
    iis_stream_impl_t *stream_impl = NULL;
    char *temp = NULL;

    AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
    stream_impl = (iis_stream_impl_t *)stream;

    if(stream_impl->cur_pos == 0)
        stream_impl->cur_position = stream_impl->lpECB->lpbData;

    /* If this is the case all the bytes are in the lpECB->lpbData buffer*/
    if(stream_impl->lpECB->cbAvailable == stream_impl->lpECB->cbTotalBytes)
    {
        /* Cannot read more than in the buffer.*/
        if(count + stream_impl->cur_pos <= stream_impl->lpECB->cbAvailable)
            data_to_read = (unsigned)count;
        else
            data_to_read = stream_impl->lpECB->cbTotalBytes - stream_impl->cur_pos;

        memcpy(buffer, stream_impl->cur_position, data_to_read);
        temp = (char *)(stream_impl->cur_position);
        temp += data_to_read;
        stream_impl->cur_position = temp;
        temp = NULL;
        stream_impl->cur_pos += data_to_read;
        read_bytes = data_to_read;
    }
    else if(stream_impl->lpECB->cbAvailable == -1)
    {
        ret_val = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, buffer, &read_bytes);
    }
    else if(stream_impl->lpECB->cbAvailable < stream_impl->lpECB->cbTotalBytes)
    {
        if(stream_impl->cur_pos > stream_impl->lpECB->cbAvailable)
        {
            ret_val = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, buffer,
                &read_bytes);
        }
        else if(stream_impl->cur_pos + count > stream_impl->lpECB->cbAvailable
            && stream_impl->cur_pos < stream_impl->lpECB->cbAvailable)
        {
            int read_length = 0;
            if(count + stream_impl->cur_pos <= stream_impl->lpECB->cbAvailable)
                read_length = (unsigned)count;
            else
                read_length = stream_impl->lpECB->cbTotalBytes - stream_impl->cur_pos;
            data_to_read = stream_impl->lpECB->cbAvailable - stream_impl->cur_pos;
            memcpy(buffer, stream_impl->cur_position, data_to_read);

            read_bytes = stream_impl->cur_pos + read_length - stream_impl->lpECB->cbAvailable;
            temp_buff = malloc(read_bytes);

            if(temp_buff == NULL)
                return data_to_read;
            ret_val = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, temp_buff,
                &read_bytes);
            memcpy(((char *)buffer + data_to_read), temp_buff, read_bytes);
            read_bytes += data_to_read;
            temp = (char *)(stream_impl->cur_position);
            temp += read_bytes;
            stream_impl->cur_position = temp;
            stream_impl->cur_pos += (unsigned)read_bytes;
        }
        else
        {
            memcpy(buffer, stream_impl->cur_position, count);
            temp = (char *)(stream_impl->cur_position);
            temp += count;
            stream_impl->cur_position = temp;
            temp = NULL;
            stream_impl->cur_pos += (unsigned)count;
            read_bytes = (int)count;
        }
    }
    if(ret_val == TRUE)
        return read_bytes;
    else
        return -1;
}

int AXIS2_CALL
iis_stream_write(
    axutil_stream_t * stream,
    const axutil_env_t * env,
    const void *buf,
    size_t count)
{
    DWORD ret_val = NO_ERROR;
    unsigned long bytes_sent = 0;
    iis_stream_impl_t *stream_impl = NULL;
    axis2_char_t *buffer = NULL;

    AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
    AXIS2_PARAM_CHECK(env->error, buf, AXIS2_FAILURE);
    stream_impl = AXIS2_INTF_TO_IMPL(stream);
    buffer = (axis2_char_t *)buf;
    bytes_sent = (unsigned)strlen(buffer);

    if(count <= 0)
    {
        return (int)count;
    }
    /* assume that buffer is not null terminated */
    ret_val = stream_impl->lpECB->WriteClient(stream_impl->lpECB->ConnID, buffer, &bytes_sent,
        HSE_IO_SYNC);
    if(ret_val == TRUE)
        return (int)bytes_sent;
    else
        return -1;
}

int AXIS2_CALL
iis_stream_skip(
    axutil_stream_t * stream,
    const axutil_env_t * env,
    int count)
{
    DWORD ret_val = TRUE;
    iis_stream_impl_t *stream_impl = NULL;
    void *temp_buff = NULL;
    int data_to_read = 0;
    DWORD read_bytes = (DWORD)count;
    char *temp = NULL;

    AXIS2_ENV_CHECK(env, AXIS2_CRITICAL_FAILURE);
    stream_impl = (iis_stream_impl_t *)stream;

    if(stream_impl->cur_pos == 0)
        stream_impl->cur_position = stream_impl->lpECB->lpbData;

    if(stream_impl->lpECB->cbAvailable == stream_impl->lpECB->cbTotalBytes)
    {
        if(count + stream_impl->cur_pos <= stream_impl->lpECB->cbAvailable)
            data_to_read = count;
        else
            data_to_read = stream_impl->lpECB->cbAvailable - stream_impl->cur_pos;

        temp = (char *)(stream_impl->cur_position);
        temp += data_to_read;
        stream_impl->cur_position = temp;
        temp = NULL;
        stream_impl->cur_pos += data_to_read;
        read_bytes = data_to_read;
    }
    else if(stream_impl->lpECB->cbAvailable == -1)
    {
        temp_buff = malloc(read_bytes);
        ret_val
            = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, temp_buff, &read_bytes);
        free(temp_buff);
    }
    else if(stream_impl->lpECB->cbAvailable < stream_impl->lpECB->cbTotalBytes)
    {
        if(stream_impl->cur_pos > stream_impl->lpECB->cbAvailable)
        {
            temp_buff = malloc(read_bytes);
            ret_val = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, temp_buff,
                &read_bytes);
            free(temp_buff);
        }
        else if(stream_impl->cur_pos + count > stream_impl->lpECB->cbAvailable
            && stream_impl->cur_pos < stream_impl->lpECB->cbAvailable)
        {
            data_to_read = stream_impl->lpECB->cbAvailable - stream_impl->cur_pos;
            read_bytes = stream_impl->cur_pos + count - stream_impl->lpECB->cbAvailable;
            temp_buff = malloc(read_bytes);

            if(temp_buff == NULL)
                return data_to_read;

            ret_val = stream_impl->lpECB->ReadClient(stream_impl->lpECB->ConnID, temp_buff,
                &read_bytes);
            read_bytes += data_to_read;
            free(temp_buff);
        }
        else
        {
            temp = (char *)(stream_impl->cur_position);
            temp += count;
            stream_impl->cur_position = temp;
            temp = NULL;
            stream_impl->cur_pos += count;
            read_bytes = count;
        }
    }
    if(ret_val == FALSE)
    {
        return -1;
    }
    return read_bytes;
}

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

    return ret;
}

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