/*
 *   Copyright 2003-2004 The Apache Software Foundation.
// (c) Copyright IBM Corp. 2004, 2005 All Rights Reserved 
 *
 *   Licensed 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.
 */

/**
 * This class 
 *
 * @author Susantha Kumara (skumara@virtusa.com, susantha@opensource.lk)
 * @author damitha kumarage (damitha@hsenid.lk, damitha@opensource.lk)
 *
 */

// !!! This include file must be first thing in file !!!
#include "../../platforms/PlatformAutoSense.hpp"

#include <stdio.h>

#include "ChannelFactory.hpp"
#include "HTTPTransportException.hpp"
#include "../../common/AxisTrace.h"

AXIS_CPP_NAMESPACE_START

#define MAXCHANNELS (int)MaxChannelCount
ChannelLibrary *ChannelFactory::m_ChannelLibrary[MAXCHANNELS] = {NULL,NULL};

ChannelFactory::
ChannelFactory()
{
    for( int iCount = 0; iCount < (int) MaxChannelCount; iCount++)
    {
        m_pLibName[iCount] = NULL;
        m_LibHandler[iCount] = NULL;
        m_pChannel[iCount] = NULL;
    }
}

ChannelFactory::
~ChannelFactory()
{
    for( int eChannelType = 0; eChannelType < (int) MaxChannelCount; eChannelType++)
    {
        UnLoadChannelLibrary( (g_ChannelType) eChannelType);
    }
}

IChannel * ChannelFactory::
LoadChannelLibrary( g_ChannelType eChannelType, const char * pcLibraryName)
{
    logEntryEngine("ChannelFactory::LoadChannelLibrary")

    DLHandler    sLibHandler;
    IChannel *    pChannel = NULL;
    int            iLibCount = (int) eChannelType;

    // Additional code added to block reloading of DLL if name has not changed.
    if( m_pLibName[iLibCount] == NULL ||
        strcmp( pcLibraryName, m_pLibName[iLibCount]) != 0)
    {
        logDebugArg1("Loading transport %s", pcLibraryName)

        sLibHandler = PLATFORM_LOADLIB( pcLibraryName);

        if( !sLibHandler)
        {
            // get load lib error information
            string sFullMessage = "Failed to load transport channel library " +  
                                  string(pcLibraryName) + ". " + PLATFORM_LOADLIB_ERROR;

            logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_LOADING_CHANNEL_FAILED", sFullMessage.c_str())

            throw HTTPTransportException( SERVER_TRANSPORT_LOADING_CHANNEL_FAILED, sFullMessage.c_str());
        }
        else
        {
            CREATE_OBJECT3 sCreate = (CREATE_OBJECT3)NULL;
            DELETE_OBJECT3 sDelete = (DELETE_OBJECT3)NULL;
            
            sCreate = (CREATE_OBJECT3) PLATFORM_GETPROCADDR( sLibHandler, CREATE_FUNCTION3);
            if (sCreate)
                sDelete = (DELETE_OBJECT3) PLATFORM_GETPROCADDR( sLibHandler, DELETE_FUNCTION3);

            if (!sCreate || !sDelete)
            {
                // get load lib error information
                string sFullMessage = "Failed to resolve to transport channel procedures in library " +
                                      string(pcLibraryName) + ". " +  PLATFORM_LOADLIB_ERROR;
                
                // Unload library - this must be done after obtaining error info above
                PLATFORM_UNLOADLIB( sLibHandler);

                if( eChannelType == UnsecureChannel)
                {
                    logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_LOADING_CHANNEL_FAILED", sFullMessage.c_str())

                    throw HTTPTransportException( SERVER_TRANSPORT_LOADING_CHANNEL_FAILED, sFullMessage.c_str());
                }
                else
                {
                    logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_LOADING_SSLCHANNEL_FAILED", sFullMessage.c_str())

                    throw HTTPTransportException( SERVER_TRANSPORT_LOADING_SSLCHANNEL_FAILED, sFullMessage.c_str());
                }
            }

            // Additional code added to that when the user wants to load a different
            // library from that which is already loaded, it will now allow the change.
            UnLoadChannelLibrary(eChannelType);
                        
            delete [] m_pLibName[iLibCount];
            m_pLibName[iLibCount] = NULL;

            m_pLibName[iLibCount] = new char[ strlen( pcLibraryName) + 1];
            strcpy( m_pLibName[iLibCount], pcLibraryName);
            m_LibHandler[iLibCount] = sLibHandler;

            if( sCreate)
            {
                sCreate( &pChannel);
                m_pChannel[iLibCount] = pChannel;
                
                if (AxisTrace::isLoggingEnabled() && AxisTrace::isTransportLoggingEnabled())
                    pChannel->enableTrace(AxisTrace::getLogFilePath().c_str(), AxisTrace::getLogFilter().c_str());
            }
        }
    }
    else
        pChannel = m_pChannel[iLibCount];

    logExitWithPointer(pChannel)
    
    return pChannel;
}

bool ChannelFactory::
UnLoadChannelLibrary( g_ChannelType eChannelType)
{
    logEntryEngine("ChannelFactory::UnLoadChannelLibrary")

    bool    bSuccess = false;
    int        iLibIndex = (int) eChannelType;

    if( m_pChannel[iLibIndex] != NULL)
    {
        if( m_LibHandler[iLibIndex] != NULL)
        {
            // If there is a channel library object handle then find the entry point in
            // the library to call the channel library destructor (DestroyInstance) which
            // in turn calls the channel destructor.  On return from this call, the
            // m_pChannel[iLibIndex] object no longer exists.
            DELETE_OBJECT3 sDelete = (DELETE_OBJECT3) PLATFORM_GETPROCADDR( m_LibHandler[iLibIndex], DELETE_FUNCTION3);
            sDelete( m_pChannel[iLibIndex]);
        }
        else
        {
            // Samisa: somehow, the above block does not seem to deallocate the channel
            // As a workaround, I delete the channel here and seems this logic is not having any side effects
            // More importantly I could get rid of the memory leak
            delete m_pChannel[iLibIndex];
        }

        m_pChannel[iLibIndex] = NULL;
    }

    // Delete library name from the library name list.
    delete [] m_pLibName[iLibIndex];
    m_pLibName[iLibIndex] = NULL;

    // If a channel library object handle is valid, then unload the library and
    // reset the handle.
    if( m_LibHandler[iLibIndex] != NULL)
    {
        PLATFORM_UNLOADLIB( m_LibHandler[iLibIndex]);
        m_LibHandler[iLibIndex] = 0;
        bSuccess = true;
    }

    logExitWithBoolean(bSuccess)
    
    return bSuccess;
}

void ChannelFactory::
preloadChannels(char *unsecChannel, char *secChannel)
{
    if (unsecChannel && strcmp(unsecChannel,"Unknown")) preloadChannel(UnsecureChannel, unsecChannel);
    if (secChannel && strcmp(secChannel,"Unknown")) preloadChannel(SecureChannel, secChannel);
}

void ChannelFactory::
preloadChannel(g_ChannelType type, const char *pcLibraryName)
{
    logEntryEngine("ChannelFactory::preloadChannel")

    int iLibCount = (int)type;
    ChannelLibrary *pCh = new ChannelLibrary();

    pCh->m_Library = PLATFORM_LOADLIB( pcLibraryName);
    if( !pCh->m_Library)
    {
        // get load lib error information
        string sFullMessage = "Failed to pre-load transport channel library " +  
                              string(pcLibraryName) + ". " + PLATFORM_LOADLIB_ERROR;
        
        delete pCh;

        logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_LOADING_CHANNEL_FAILED", sFullMessage.c_str())

        throw HTTPTransportException( SERVER_TRANSPORT_LOADING_CHANNEL_FAILED, sFullMessage.c_str());
    }

    pCh->m_Create = (CREATE_OBJECT3) PLATFORM_GETPROCADDR( pCh->m_Library, CREATE_FUNCTION3);
    if (pCh->m_Create)
        pCh->m_Delete = (DELETE_OBJECT3) PLATFORM_GETPROCADDR( pCh->m_Library, DELETE_FUNCTION3);
        
    if (!pCh->m_Create || !pCh->m_Delete)
    {
        // get load lib error information
        string sFullMessage = "Failed to resolve to transport channel procedures in library " +
                              string(pcLibraryName) + ". " +  PLATFORM_LOADLIB_ERROR;
        
        // Unload library - this must be done after obtaining error info above
        PLATFORM_UNLOADLIB( pCh->m_Library);
        
        delete pCh;

        if( type == UnsecureChannel)
        {
            logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_LOADING_CHANNEL_FAILED", sFullMessage.c_str())

            throw HTTPTransportException( SERVER_TRANSPORT_LOADING_CHANNEL_FAILED, sFullMessage.c_str());
        }
        else
        {
            logThrowExceptionWithData("HTTPTransportException - SERVER_TRANSPORT_LOADING_SSLCHANNEL_FAILED", sFullMessage.c_str())

            throw HTTPTransportException( SERVER_TRANSPORT_LOADING_SSLCHANNEL_FAILED, sFullMessage.c_str());
        }
    }

    m_ChannelLibrary[iLibCount] = pCh;
    
    logExit()
}

IChannel *ChannelFactory::
createChannel(g_ChannelType type) 
{
    logEntryEngine("ChannelFactory::createChannel")

    int iLibCount = (int)type;
    IChannel *pChannel = NULL;
    if (m_ChannelLibrary[iLibCount])
    {
        m_ChannelLibrary[iLibCount]->m_Create(&pChannel);
        m_pChannel[iLibCount] = pChannel;
        
        if (AxisTrace::isLoggingEnabled() && AxisTrace::isTransportLoggingEnabled())
            pChannel->enableTrace(AxisTrace::getLogFilePath().c_str(), AxisTrace::getLogFilter().c_str());
    }
    
    logExitWithPointer(pChannel)

    return pChannel;
}

void ChannelFactory::
unloadChannels()
{
    logEntryEngine("ChannelFactory::unloadChannels")

    for (int i=0; i<(int)MaxChannelCount; i++) 
    {
        if (m_ChannelLibrary[i])
        {
            PLATFORM_UNLOADLIB(m_ChannelLibrary[i]->m_Library);
            delete m_ChannelLibrary[i];
            m_ChannelLibrary[i] = NULL;
        }
    }
    
    logExit()
}

AXIS_CPP_NAMESPACE_END
