/*
 * Copyright 2009 Funambol, Inc.
 *
 * 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 i<s 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.
 */

/* $Id$ */

#include "SEMConfig.h"

#include <base/Log.h>
#include "Logger/LoggerMacroses.h"


#define SEM_CERTIFICATES_LOCATION "CertificatesLocation"
#define SEM_CONNECTION_DELAY      "ConnectionDelay"

#define SEM_DEFAULT_ACCOUNT_NAME  "DefaultAccountName"
#define SEM_DEFAULT_FWURI         "DefaultFWURI"
#define SEM_BLUE_AVALANCHE_ACCOUNT_NAME     "BlueAvalancheAccountName"

#define SEM_DUMP_MESSAGE_PATH     "DumpMessagesPath"
#define SEM_LOG_TRANSPORT_LAYER   "LogTransportLayer"

#define SEM_MAX_MSG_SIZE          "MaxMsgSize"
#define SEM_MAX_OBJ_SIZE          "MaxObjSize"

#define SEM_NEW_LINES_IN_MESSAGE  "NewLinesInMessage"
#define SEM_OEM_SHARED_KEY        "OEMSharedKey"

#define SEM_POLLING_ATTEMPTS      "PollingAttempts"
#define SEM_POLLING_INTERVAL      "PollingInterval"
#define SEM_POLLING_SUPPORTED     "PollingSupported"

#define SEM_SHORT_TIMEOUT         "ShortTimeout"
#define SEM_SSL_VERIFY_HOST       "SSLVerifyHost"
#define SEM_SSL_VERIFY_SERVER     "SSLVerifyServer"
#define SEM_START_ON_LAN          "StartOnLAN"
#define SEM_USER_AGENT_NAME       "UserAgentName"
#define SEM_WBXML_SESSION         "WBXMLSession"

#define SEM_WIB_RETRIES_COUNT     "WIBRetries"
#define SEM_WIB_RETRY_INTERVAL    "WIBRetryInterval"
#define SEM_WIB_PLAIN_BOOTSTRAP   "WIBPlainBootstrap"
#define SEM_WIB_PLAIN_BOOTSTRAP_CIPHER_HEADER    "WIBPlainBootstrapCipherHeaderPresent"
#define SEM_WIB_SERVICE_DISCOVERY_TARGET    "WIBServiceDiscoveryTarget"
#define SEM_WIB_DNS_SERVER        "WIBDNSServer"
#define SEM_WIB_SERVER            "WIBServer"
#define SEM_WIB_SERVER_PORT       "WIBServerPort"
#define SEM_WIB_REQUEST_URI       "WIBRequestURI"
#define SEM_MULTIPLE_BOOTSTRAP    "MultipleBootstrap"


using namespace NS_DM_Client;
using namespace NS_DM_Client::NS_Communication;

static const char * c_LogName = "ServerExchangeManager";
static const int c_DefaultMaxMsgSize = 8196;
static const int c_DefaultMaxObjSize = 32*1024;


void SEMConfig::operator()(ServerExchangeManager &sem, const StringMap& settings)
{
    StringMap *map = const_cast<StringMap*>(&settings);
    
    const FStringBuffer &certsLocation    = map->get(SEM_CERTIFICATES_LOCATION);
    if (!certsLocation.empty())
        sem.m_settings.CertificatesLocation   = certsLocation;
    
    const FStringBuffer &connDelay        = map->get(SEM_CONNECTION_DELAY);
    if (!connDelay.empty())
        sem.m_connectionDelay = 1000*atoi(connDelay.c_str());
    
    const FStringBuffer &sslVerifyServer  = map->get(SEM_SSL_VERIFY_SERVER);
    sem.m_settings.SSLVerifyServer = sslVerifyServer.empty() ? true : atoi(sslVerifyServer.c_str()) != 0;
    
    const FStringBuffer  &sslVerifyHost   = map->get(SEM_SSL_VERIFY_HOST);
    sem.m_settings.SSLVerifyHost = sslVerifyHost.empty() ? true : atoi(sslVerifyHost.c_str()) != 0;
    
    const FStringBuffer &propMaxObjSize   = map->get(SEM_MAX_OBJ_SIZE);
    sem.m_settings.MaxObjSize = (propMaxObjSize.empty()) ? 0 : atoi(propMaxObjSize.c_str());
    if (sem.m_settings.MaxObjSize == 0)
        sem.m_settings.MaxObjSize = c_DefaultMaxObjSize;
    
    const FStringBuffer &propMaxMsgSize   = map->get(SEM_MAX_MSG_SIZE);
    sem.m_settings.MaxMsgSize = (propMaxMsgSize.empty()) ? 0 : atoi(propMaxMsgSize.c_str());
    if (sem.m_settings.MaxMsgSize == 0)
        sem.m_settings.MaxMsgSize = c_DefaultMaxMsgSize;
    
//  const FStringBuffer &defaultFWURI     = map->get(SEM_DEFAULT_FWURI);
//  if (!defaultFWURI.empty())
//      sem.m_defaultFWURI = defaultFWURI.c_str();
    
    const FStringBuffer &startOnLAN       = map->get(SEM_START_ON_LAN);
    sem.m_startOnLAN = (!startOnLAN.empty() && startOnLAN.icmp("1")) ? true : false;
    
    const FStringBuffer & sbDAccName      = map->get(SEM_DEFAULT_ACCOUNT_NAME);
    if (!sbDAccName.empty())
        sem.m_defaultAccountName = sbDAccName.c_str();
    
    const FStringBuffer & sbDRMDAccName   = map->get(SEM_BLUE_AVALANCHE_ACCOUNT_NAME);
    if (!sbDRMDAccName.empty())
        sem.m_drmdAccountName = sbDRMDAccName.c_str();
    
    const FStringBuffer& userAgentName    = map->get(SEM_USER_AGENT_NAME);
    if (!userAgentName.empty())
        sem.m_settings.UserAgentName = userAgentName;
    
    const FStringBuffer& oemSharedKey     = map->get(SEM_OEM_SHARED_KEY);
    if (!oemSharedKey.empty())
        sem.m_OEMSharedKey = oemSharedKey.c_str();
    
    const FStringBuffer& newLines         = map->get(SEM_NEW_LINES_IN_MESSAGE);
    if (!newLines.empty())
        sem.m_settings.KeepNewLines = newLines.icmp("1");
    
    const FStringBuffer &propWBXMLSession = map->get(SEM_WBXML_SESSION);
    const char *cWBXMLSession = propWBXMLSession.c_str();
    bool useWBXML = false;
    if (cWBXMLSession)
    {
        if (!strcmp("1", cWBXMLSession))
        {
            useWBXML = true;
        }
        else if (strcmp("0", cWBXMLSession))
        {
            GDLERROR("Incorrect value of the 'WBXMLSession' property: [%s]; expected are [0,1]", cWBXMLSession);
        }
    }
    sem.m_settings.UseWBXML = useWBXML;
    
    
    // read server polling settings
    const FStringBuffer & sbAttempts(map->get(SEM_POLLING_ATTEMPTS));
    const FStringBuffer & sbInterval(map->get(SEM_POLLING_INTERVAL));
    const FStringBuffer & sbSupported(map->get(SEM_POLLING_SUPPORTED));
    
    if (!sbAttempts.empty())
        sem.m_serverPoller.URIPollingAttempts = sbAttempts.c_str();
    if (!sbInterval.empty())
        sem.m_serverPoller.URIPollingInterval = sbInterval.c_str();
    if (!sbSupported.empty())
        sem.m_serverPoller.URIPollingSupported = sbSupported.c_str();
    
    const FStringBuffer  &shortTimeout   = map->get(SEM_SHORT_TIMEOUT);
    sem.m_useShortTimeout = shortTimeout.empty() ? false : atoi(shortTimeout.c_str()) != 0;
    
    const FStringBuffer& dumpPath      = map->get(SEM_DUMP_MESSAGE_PATH);
    if (!dumpPath.empty())
        sem.m_settings.MessagesDumpPath = dumpPath;
    
    const FStringBuffer& transportLog  = map->get(SEM_LOG_TRANSPORT_LAYER);
    if (transportLog == "1")
    {
        configureTransportLogger();
    }
    
    const FStringBuffer  &wibReties   = map->get(SEM_WIB_RETRIES_COUNT);
    sem.m_wibRetriesCount = wibReties.empty() ? 0 : atoi(wibReties.c_str());
    
    const FStringBuffer  &wibRetryInterval   = map->get(SEM_WIB_RETRY_INTERVAL);
    sem.m_wibRetryInterval = wibRetryInterval.empty() ? 0 : atoi(wibRetryInterval.c_str());
    
    const Funambol::StringBuffer& plainBootstrapParam = map->get(SEM_WIB_PLAIN_BOOTSTRAP);
    sem.m_wibPlainBootstrap = (plainBootstrapParam.empty()) ? false : atoi(plainBootstrapParam.c_str()) != 0;
    
    const Funambol::StringBuffer& plainBootstrapCipherHdrParam = map->get(SEM_WIB_PLAIN_BOOTSTRAP_CIPHER_HEADER);
    sem.m_wibCipherHeaderPresent = (plainBootstrapCipherHdrParam.empty()) ? false : atoi(plainBootstrapCipherHdrParam.c_str()) != 0;
    
    const Funambol::StringBuffer& wibServiceDiscoveryTarget = map->get(SEM_WIB_SERVICE_DISCOVERY_TARGET);
    sem.m_wibServiceDiscoveryTarget = (wibServiceDiscoveryTarget.empty()) ? "" : wibServiceDiscoveryTarget;
    
    const Funambol::StringBuffer& wibDnsServer = map->get(SEM_WIB_DNS_SERVER);
    sem.m_wibDnsServer = (wibDnsServer.empty()) ?  "" : wibDnsServer;

    const Funambol::StringBuffer& wibServer = map->get(SEM_WIB_SERVER);
    sem.m_wibServer = (wibServer.empty()) ?  "" : wibServer;

    const FStringBuffer  &wibServerPort   = map->get(SEM_WIB_SERVER_PORT);
    sem.m_wibServerPort = wibServerPort.empty() ? 0 : atoi(wibServerPort.c_str());

    const Funambol::StringBuffer& wibRequestURI = map->get(SEM_WIB_REQUEST_URI);
    sem.m_wibRequestURI = (wibRequestURI.empty()) ?  "" : wibRequestURI;

    const FStringBuffer &multiBootstrap       = map->get(SEM_MULTIPLE_BOOTSTRAP);
    sem.m_multipleBootstrap = (!multiBootstrap.empty() && multiBootstrap.icmp("1")) ? true : false;

    GDLINFO("DefaultAccountName: '%s'", sem.m_defaultAccountName.c_str());
    printConfig(settings);
}


void SEMConfig::configureTransportLogger()
{
#if defined(PLATFORM_POSIX)
    Funambol::Log::instance().setLogPath("/tmp");
#elif defined(PLATFORM_WINDOWS)
    Funambol::Log::instance().setLogPath("c:/Windows/Temp");
#endif
    Funambol::Log::instance().setLogName("dmclient_transport.log");
    Funambol::Log::instance().setLevel(Funambol::LOG_LEVEL_DEBUG);
}


void SEMConfig::printConfig(const StringMap& settings)
{
    GDLDEBUG("ServerExchangeManager config:");
    StringMap *map = const_cast<StringMap*>(&settings);
    
    GDLDEBUG("  CertificatesLocation '%s'", map->get(SEM_CERTIFICATES_LOCATION).c_str());
    GDLDEBUG("  ConnectionDelay      '%s'", map->get(SEM_CONNECTION_DELAY).c_str());
    GDLDEBUG("  SSLVerifyServer      '%s'", map->get(SEM_SSL_VERIFY_SERVER).c_str());
    GDLDEBUG("  SSLVerifyHost        '%s'", map->get(SEM_SSL_VERIFY_HOST).c_str());
    GDLDEBUG("  MaxObjSize           '%s'", map->get(SEM_MAX_OBJ_SIZE).c_str());
    GDLDEBUG("  MaxMsgSize           '%s'", map->get(SEM_MAX_MSG_SIZE).c_str());
    GDLDEBUG("  DefaultFWURI         '%s'", map->get(SEM_DEFAULT_FWURI).c_str());
    GDLDEBUG("  StartOnLAN           '%s'", map->get(SEM_START_ON_LAN).c_str());
    GDLDEBUG("  DefaultAccountName   '%s'", map->get(SEM_DEFAULT_ACCOUNT_NAME).c_str());
    GDLDEBUG("  BlueAvalancheAccountName      '%s'", map->get(SEM_BLUE_AVALANCHE_ACCOUNT_NAME).c_str());
    GDLDEBUG("  UserAgentName        '%s'", map->get(SEM_USER_AGENT_NAME).c_str());
    GDLDEBUG("  OEMSharedKey         '%s'", map->get(SEM_OEM_SHARED_KEY).c_str());
    GDLDEBUG("  KeepNewLines         '%s'", map->get(SEM_NEW_LINES_IN_MESSAGE).c_str());
    GDLDEBUG("  WBXMLSession         '%s'", map->get(SEM_WBXML_SESSION).c_str());
    GDLDEBUG("  URIPollingAttempts   '%s'", map->get(SEM_POLLING_ATTEMPTS).c_str());
    GDLDEBUG("  URIPollingInterval   '%s'", map->get(SEM_POLLING_INTERVAL).c_str());
    GDLDEBUG("  URIPollingSupported  '%s'", map->get(SEM_POLLING_SUPPORTED).c_str());
    GDLDEBUG("  MessagesDumpPath     '%s'", map->get(SEM_DUMP_MESSAGE_PATH).c_str());
    GDLDEBUG("  LogTransport         '%s'", map->get(SEM_LOG_TRANSPORT_LAYER).c_str());
    GDLDEBUG("  WIBRetriesCount      '%s'", map->get(SEM_WIB_RETRIES_COUNT).c_str());
    GDLDEBUG("  WIBRetryInterval     '%s'", map->get(SEM_WIB_RETRY_INTERVAL).c_str());
    GDLDEBUG("  PlainBootstrap       '%s'", map->get(SEM_WIB_PLAIN_BOOTSTRAP).c_str());
    GDLDEBUG("  PlainBootstrapCipher '%s'", map->get(SEM_WIB_PLAIN_BOOTSTRAP_CIPHER_HEADER).c_str());
    GDLDEBUG("  WIBServiceDiscoveryTarget '%s'", map->get(SEM_WIB_SERVICE_DISCOVERY_TARGET).c_str());
    GDLDEBUG("  WIBDNSServer         '%s'", map->get(SEM_WIB_DNS_SERVER).c_str());
    GDLDEBUG("  WIBServer            '%s'", map->get(SEM_WIB_SERVER).c_str());
    GDLDEBUG("  WIBRequestURI        '%s'", map->get(SEM_WIB_REQUEST_URI).c_str());
    GDLDEBUG("  WIBServerPort        '%s'", map->get(SEM_WIB_SERVER_PORT).c_str());
    GDLDEBUG("  MultipleBootstrap    '%s'", map->get(SEM_MULTIPLE_BOOTSTRAP).c_str());

}
