/*
 * 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 <log4cxx/db/dbappender.h>
#include <log4cxx/appenderskeleton.h>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/pool.h>
#include <log4cxx/helpers/loglog.h>
#include <log4cxx/patternlayout.h>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/pattern/loggerpatternconverter.h>
#include <log4cxx/pattern/classnamepatternconverter.h>
#include <log4cxx/pattern/datepatternconverter.h>
#include <log4cxx/pattern/filelocationpatternconverter.h>
#include <log4cxx/pattern/fulllocationpatternconverter.h>
#include <log4cxx/pattern/shortfilelocationpatternconverter.h>
#include <log4cxx/pattern/linelocationpatternconverter.h>
#include <log4cxx/pattern/messagepatternconverter.h>
#include <log4cxx/pattern/methodlocationpatternconverter.h>
#include <log4cxx/pattern/levelpatternconverter.h>
#include <log4cxx/pattern/threadpatternconverter.h>
#include <log4cxx/pattern/threadusernamepatternconverter.h>
#include <log4cxx/pattern/ndcpatternconverter.h>
#include <log4cxx/private/appenderskeleton_priv.h>
#include <apr_dbd.h>
#include <assert.h>

using namespace LOG4CXX_NS;
using namespace LOG4CXX_NS::helpers;
using namespace LOG4CXX_NS::db;
using namespace LOG4CXX_NS::spi;
using namespace LOG4CXX_NS::pattern;

IMPLEMENT_LOG4CXX_OBJECT(DBAppender)

#define _priv static_cast<DBAppenderPriv*>(m_priv.get())

struct DBAppender::DBAppenderPriv : public AppenderSkeleton::AppenderSkeletonPrivate
{
    DBAppenderPriv() :
        AppenderSkeletonPrivate()
	{
		static bool initialized = false;
		if (!initialized)
		{
			initialized = true;
			apr_status_t stat = apr_dbd_init(m_pool.getAPRPool());
			assert(stat == APR_SUCCESS);
		}
	}

    apr_dbd_driver_t* m_driver = nullptr;
    apr_dbd_t* m_databaseHandle = nullptr;
    apr_dbd_prepared_t* preparedStmt = nullptr;
    std::vector<LogString> mappedName;
    std::string driverName;
    std::string driverParams;
    std::string databaseName;
    std::string sqlStatement;
    Pool m_pool;
    std::vector<pattern::LoggingEventPatternConverterPtr> converters;
};

#define RULES_PUT(spec, cls) \
    specs.insert(PatternMap::value_type(LogString(LOG4CXX_STR(spec)), cls ::newInstance))

static PatternMap getFormatSpecifiers()
{
    PatternMap specs;
    if (specs.empty())
    {
        RULES_PUT("logger", LoggerPatternConverter);
        RULES_PUT("class", ClassNamePatternConverter);
        RULES_PUT("time", DatePatternConverter);
        RULES_PUT("shortfilename", ShortFileLocationPatternConverter);
        RULES_PUT("fullfilename", FileLocationPatternConverter);
        RULES_PUT("location", FullLocationPatternConverter);
        RULES_PUT("line", LineLocationPatternConverter);
        RULES_PUT("message", MessagePatternConverter);
        RULES_PUT("method", MethodLocationPatternConverter);
        RULES_PUT("level", LevelPatternConverter);
        RULES_PUT("thread", ThreadPatternConverter);
        RULES_PUT("threadname", ThreadUsernamePatternConverter);
        RULES_PUT("ndc", NDCPatternConverter);
    }
    return specs;
}

DBAppender::DBAppender()
    : AppenderSkeleton (std::make_unique<DBAppenderPriv>())
{
}

DBAppender::~DBAppender()
{
    close();
}

void DBAppender::close(){
    if(_priv->m_driver && _priv->m_databaseHandle){
        apr_dbd_close(_priv->m_driver, _priv->m_databaseHandle);
    }
    _priv->m_driver = nullptr;
    _priv->m_databaseHandle = nullptr;
}

void DBAppender::setOption(const LogString& option, const LogString& value){
    if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("COLUMNMAPPING"), LOG4CXX_STR("columnmapping")))
    {
        _priv->mappedName.push_back(value);
    }
    else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("DRIVERNAME"), LOG4CXX_STR("drivername")))
    {
        Transcoder::encodeUTF8(value, _priv->driverName);
    }
    else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("DRIVERPARAMS"), LOG4CXX_STR("driverparams")))
    {
        Transcoder::encodeUTF8(value, _priv->driverParams);
    }
    else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("DATABASENAME"), LOG4CXX_STR("databasename")))
    {
        Transcoder::encodeUTF8(value, _priv->databaseName);
    }
    else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("SQL"), LOG4CXX_STR("sql")))
    {
        Transcoder::encodeUTF8(value, _priv->sqlStatement);
    }
    else
    {
        AppenderSkeleton::setOption(option, value);
    }
}

void DBAppender::activateOptions(helpers::Pool& p){
    apr_status_t stat = apr_dbd_get_driver(_priv->m_pool.getAPRPool(),
                                           _priv->driverName.c_str(),
                                           const_cast<const apr_dbd_driver_t**>(&_priv->m_driver));

    if(stat != APR_SUCCESS){
        LogString errMsg = LOG4CXX_STR("Unable to get driver named ");
        LOG4CXX_DECODE_CHAR(driverName, _priv->driverName);
        errMsg.append(driverName);
        LogLog::error(errMsg);
        _priv->errorHandler->error(errMsg);
        return;
    }

    stat = apr_dbd_open(_priv->m_driver,
                        _priv->m_pool.getAPRPool(),
                        _priv->driverParams.c_str(),
                        &_priv->m_databaseHandle);
    if(stat != APR_SUCCESS){
        LogLog::error(LOG4CXX_STR("Unable to open database"));
        _priv->errorHandler->error(LOG4CXX_STR("Unable to open database"));
        return;
    }

    if(!_priv->databaseName.empty()){
        apr_dbd_set_dbname(_priv->m_driver,
                           _priv->m_pool.getAPRPool(),
                           _priv->m_databaseHandle,
                           _priv->databaseName.c_str());
    }

    stat = apr_dbd_prepare(_priv->m_driver,
                           _priv->m_pool.getAPRPool(),
                           _priv->m_databaseHandle,
                           _priv->sqlStatement.c_str(),
                           "log_insert",
                           &_priv->preparedStmt);
    if(stat != APR_SUCCESS){
        LogString error = LOG4CXX_STR("Unable to prepare statement: ");
        std::string dbdErr(apr_dbd_error(_priv->m_driver, _priv->m_databaseHandle, stat));
        LOG4CXX_DECODE_CHAR(dbdErrLS, dbdErr);
        error.append(dbdErrLS);
        LogLog::error(error);
        _priv->errorHandler->error(error);
        return;
    }

    auto specs = getFormatSpecifiers();
    for (auto& name : _priv->mappedName)
    {
        auto pItem = specs.find(StringHelper::toLowerCase(name));
        if (specs.end() == pItem)
            LogLog::error(name + LOG4CXX_STR(" is not a supported ColumnMapping value"));
        else
        {
            std::vector<LogString> options;
            if (LOG4CXX_STR("time") == pItem->first)
                options.push_back(LOG4CXX_STR("yyyy-MM-ddTHH:mm:ss.SSS"));
            pattern::LoggingEventPatternConverterPtr converter = LOG4CXX_NS::cast<LoggingEventPatternConverter>((pItem->second)(options));
            _priv->converters.push_back(converter);
        }
    }
}

void DBAppender::append(const spi::LoggingEventPtr& event, helpers::Pool& p){
	std::vector<std::string> ls_args;
    std::vector<const char*> args;
    int stat;
    int num_rows;

    if(_priv->m_driver == nullptr ||
            _priv->m_databaseHandle == nullptr ||
            _priv->preparedStmt == nullptr){
        _priv->errorHandler->error(LOG4CXX_STR("DBAppender not initialized properly: logging not available"));
        return;
    }

    for(auto& converter : _priv->converters){
        LogString str_data;
        converter->format(event, str_data, p);
		LOG4CXX_ENCODE_CHAR(new_str_data, str_data);
		ls_args.push_back(new_str_data);
    }

	for(std::string& str : ls_args){
        args.push_back(str.data());
    }
    args.push_back(nullptr);

    stat = apr_dbd_pquery(_priv->m_driver,
                          _priv->m_pool.getAPRPool(),
                          _priv->m_databaseHandle,
                          &num_rows,
                          _priv->preparedStmt,
                          int(args.size()),
                          args.data());
    if(stat != APR_SUCCESS){
        LogString error = LOG4CXX_STR("Unable to insert: ");
		LOG4CXX_DECODE_CHAR(local_error, apr_dbd_error(_priv->m_driver, _priv->m_databaseHandle, stat));
		error.append(local_error);
        LogLog::error(error);
        _priv->errorHandler->error(error);
    }
}
