#include <QString>
#include <QSettings>
#include <QDate>
#include <QDateTime>
#include <QVariant>
#include <QStringList>
#include <QFile>
#include <QVector>
#include <iostream>
#include <QTextStream>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>
#include "sinitializer.h"
#include "../common.h"
using namespace std;
/*
bool SInitializer::disableIndex(QSqlDatabase& db, QString _tableName, QStringList _strIndexNames, int _nMode)
{
    if (_nMode == DEBUG)
    {
        return true;
    }

    QSqlQuery query(db);

    foreach (const QString& strIndex, _strIndexNames)
    {
        QString strQuery = "alter table " + _tableName + " drop index " + strIndex;

        if(!query.exec(strQuery.toUtf8()))
        {
            insertLog(query.lastQuery());
            insertLog(query.lastError().text());
            return false;
        }
    }
    return true;
}

bool SInitializer::enableIndex(QSqlDatabase& db, QString _tableName, QStringList _strIndexNames, int _nMode)
{
    if (_nMode == DEBUG)
    {
        return true;
    }

    QSqlQuery query(db);
    foreach (const QString& strIndex, _strIndexNames)
    {
        QString strQuery = "alter table " + _tableName + " add index (" +strIndex + ")";
        if(!query.exec(strQuery.toUtf8()))
        {
            insertLog(query.lastQuery());
            insertLog(query.lastError().text());
            return false;
        }
    }
    return true;
}

bool SInitializer::disableSettings(QSqlDatabase& db, int _nMode)
{
    if (_nMode == DEBUG)
    {
        return true;
    }
    QSqlQuery query(db);
    QString strQuery = "SET AUTOCOMMIT = 0; SET FOREIGN_KEY_CHECKS = 0; SET UNIQUE_CHECKS = 0";
    if(!query.exec(strQuery))
    {
        insertLog(query.lastQuery());
        insertLog(query.lastError().text());
        return false;
    }
    return true;
}

bool SInitializer::enableSettings(QSqlDatabase& db, int _nMode)
{
    if (_nMode == DEBUG)
    {
        return true;
    }
    QSqlQuery query(db);
    QString strQuery = "SET AUTOCOMMIT = 1; SET FOREIGN_KEY_CHECKS = 1; SET UNIQUE_CHECKS = 1";
    if(!query.exec(strQuery))
    {
        insertLog(query.lastQuery());
        insertLog(query.lastError().text());
        return false;
    }
    return true;
}
*/

void SInitializer::updateWebDBInfoState(QSqlDatabase &_db, int _nCompany, QString _strStatus)
{
    QString strQuery = "update dbinfo set "
            "status = '" + _strStatus + "' "
            "where company_num = " + QString::number(_nCompany);
    _db.exec(strQuery.toUtf8());
}

void SInitializer::updateWebDBInfoComplete(QSqlDatabase _db, QString _mindate, QString _maxdate, QString _lastupdate, int _bodycount, int _replycount, int _nCompany)
{
    QString strQuery = "update dbinfo set "
            "bodycount = " + QString::number(_bodycount) + " , "
            "replycount = " + QString::number(_replycount)+" , "
            "mindate = '" + _mindate + "',"
            "maxdate = '" + _maxdate + "',"
            "lastupdate = '" + _lastupdate + "' "
            "where company_num = " + QString::number(_nCompany);
    _db.exec(strQuery.toUtf8());
}


bool SInitializer::initDays()
{
    QSettings settings(QString("setup.ini"), QSettings::IniFormat);
    settings.setIniCodec("UTF-8");
    settings.beginGroup(QString("settings"));
    if (settings.childKeys().size() == 0) return false;
    int nCutDays = settings.value("days").toInt();

    QString strFrom = settings.value("from").toString().trimmed();
    QString strTo = settings.value("to").toString().trimmed();

    if(!strFrom.isEmpty())
    {
        m_strStartDay = strFrom;
    }
    else
    {
        m_strStartDay = QDate::currentDate().addDays(-abs(nCutDays)).toString("yyyy-MM-dd");
    }
    if(!strTo.isEmpty())
    {
        m_strEndDay = strTo;
    }
    else
    {
        m_strEndDay = QDate::currentDate().toString("yyyy-MM-dd");
    }
    settings.endGroup();
    return true;
}

bool SInitializer::initSpammer()
{
    QSettings settings(QString("setup.ini"), QSettings::IniFormat);
    settings.setIniCodec("UTF-8");
    settings.beginGroup(QString("spammers"));

    if (settings.childKeys().size() == 0) return false;
    m_adSpammerParam[E_SPAMER_BODY_COUNT_CUT] = settings.value("body_cut").toDouble();
    m_adSpammerParam[E_SPAMER_BODY_COUNT_RATIO] = settings.value("body_ratio").toDouble();
    m_adSpammerParam[E_SPAMER_REPLY_COUNT_CUT] = settings.value("reply_cut").toDouble();
    m_adSpammerParam[E_SPAMER_REPLY_COUNT_RATIO] = settings.value("reply_ratio").toDouble();
    m_adSpammerParam[E_SPAMER_NICK_COUNT_CUT] = settings.value("nick_cut").toDouble();
    m_adSpammerParam[E_SPAMER_NICK_COUNT_RATIO] = settings.value("nick_ratio").toDouble();
    settings.endGroup();

    return true;
}

bool SInitializer::initDBConnection()
{
    QSettings settings(QString("setup.ini"), QSettings::IniFormat);
    settings.setIniCodec("UTF-8");
    settings.beginGroup(QString("database"));
    if (settings.childKeys().size() == 0) return false;
    m_stWebDBInfo.m_strHostName = settings.value("host").toString();
    m_stWebDBInfo.m_strUserName = settings.value("user").toString();
    m_stWebDBInfo.m_strPassword = settings.value("pass").toString();
    m_stWebDBInfo.m_strDBName = settings.value("name").toString();
    settings.endGroup();


    m_sDBManager.addDatabase("DATA", SDBManager::E_DATABASE_DATA, QString("bigbird.iptime.org"),
                             QString("admin"), QString("admin123"), QString("concepters"));

    m_sDBManager.addDatabase("WEB", SDBManager::E_DATABASE_WEB,
                             m_stWebDBInfo.m_strHostName, m_stWebDBInfo.m_strUserName,
                             m_stWebDBInfo.m_strPassword, m_stWebDBInfo.m_strDBName);


    if(!m_sDBManager.open("DATA"))
    {
        insertLog("DATA DB open failed");
        return false;
    }
    if(!m_sDBManager.open("WEB"))
    {
        insertLog("WEB DB open failed");
        return false;
    }

    return true;
}

bool SInitializer::init(const QString& _strFilterProcessGroupID, const QString& _strFilterProcessGroupName)
{
    m_stFilterProcessGroup.m_nFilterProcessGroupID = _strFilterProcessGroupID.toInt();
    m_stFilterProcessGroup.m_strFilterProcessGroupName = _strFilterProcessGroupName;

    bool b_ok = true;
    b_ok &= initDBConnection();
    b_ok &= initColumn();
    b_ok &= initDays();
    b_ok &= initInfluencer();
    b_ok &= initSpammer();
    b_ok &= initFilterProcess();
    b_ok &= initCompanyNum();
    b_ok &= initPlatform();
    //b_ok &= initConsumerCategory();
    b_ok &= initCategory();
/*
    if (!b_ok)
        cout << "FALSE" << endl;
    else
        cout << "TRUE" << endl;
*/
    return b_ok;
}

bool SInitializer::initInfluencer()
{
    m_stInfluencerParam.m_dBody = 0.4;
    m_stInfluencerParam.m_dReply = 0.6;
    return true;
}


bool SInitializer::initFilterProcess()
{
    QString strQuery = QString("select filterprocess_type,datagroup_id,filtergroup_id,company_num,category_num,filterprocess_order,service_num "
                               "from filterprocess where filterprocessgroup_id = ") + QString::number(m_stFilterProcessGroup.m_nFilterProcessGroupID);

    QSqlQuery query(m_sDBManager[SDBManager::E_DATABASE_DATA]);

    if(query.exec(strQuery.toUtf8()) == false)
    {
        insertLog(query.lastQuery());
        insertLog(query.lastError().text());
        return false;
    }

    while(query.next())
    {
        stFilterProcess stfilterprocess;
        stfilterprocess.m_nFilterProcessType = query.value(0).toInt();
        stfilterprocess.m_nDatagroupID = query.value(1).toInt();
        stfilterprocess.m_nFilterGroupID = query.value(2).toInt();
        stfilterprocess.m_nCompanyNum = query.value(3).toInt();
        stfilterprocess.m_nCategoryNum = query.value(4).toInt();
        stfilterprocess.m_nFilterProcessOrder = query.value(5).toInt();
        stfilterprocess.m_nServiceNum = query.value(6).toInt();
        m_listFilterProcess.append(stfilterprocess);
    }

    query.clear();
    strQuery = "select type, data from filter where filtergroup_id = ";
    foreach (const stFilterProcess& stfilterprocess, m_listFilterProcess)
    {
        if (stfilterprocess.m_nFilterGroupID == 0)
            continue;

        if (!query.exec(QString(strQuery + QString::number(stfilterprocess.m_nFilterGroupID)).toUtf8()))
        {
            insertLog(query.lastQuery());
            insertLog(query.lastError().text());
            return false;
        }
        QList<stFilter> listFilter;

        while (query.next())
        {
            stFilter stfilter;
            stfilter.m_nFilterGroupID = stfilterprocess.m_nFilterGroupID;
            stfilter.m_vData = query.value(1);
            stfilter.m_nType = query.value(0).toInt();
            listFilter.append(stfilter);
        }
        if (!m_mapFilterGroup.contains(stfilterprocess.m_nFilterGroupID))
            m_mapFilterGroup.insert(stfilterprocess.m_nFilterGroupID, listFilter);

    }
    return true;
}

bool SInitializer::initCategory()
{
    for (int i = 0; i < E_SERVICE_MAX; i++)
    {
        m_anAllCategory[i] = -1;
    }
    int company_num = -1;
    foreach (const stFilterProcess& stfilterprocess, m_listFilterProcess)
    {
        if (stfilterprocess.m_nFilterProcessType == 2)
        {
            company_num = stfilterprocess.m_nCompanyNum;
        }
    }
    if (company_num == -1)
        return false;

    QSqlQuery query(m_sDBManager[SDBManager::E_DATABASE_WEB]);

    QString strQuery = "select num, servicenum from category where company_num = ";
    strQuery += QString::number(company_num) + " order by servicenum asc, num asc";

    if (query.exec(strQuery.toUtf8()) == false)
    {
        insertLog(query.lastQuery());
        insertLog(query.lastError().text());
        return false;
    }

    int nService[E_SERVICE_MAX] = {0,};

    while(query.next())
    {
        switch(query.value(1).toInt())
        {
        case E_SERVICE_INFLUENCER:
        {
            if (0 == nService[E_SERVICE_INFLUENCER]++)
            {
                m_anAllCategory[E_SERVICE_INFLUENCER] = query.value(0).toInt();
            }
            break;
        }
        case E_SERVICE_CONSUMER:
        {
            if (0 == nService[E_SERVICE_CONSUMER]++)
            {
                m_anAllCategory[E_SERVICE_CONSUMER] = query.value(0).toInt();
            }
            break;
        }
        case E_SERVICE_SPAMMER:
        {
            if (0 == nService[E_SERVICE_SPAMMER]++)
            {
                m_anAllCategory[E_SERVICE_SPAMMER] = query.value(0).toInt();
            }
            break;
        }
        case E_SERVICE_POWERCAFE:
        {
            if (0 == nService[E_SERVICE_POWERCAFE]++)
            {
                m_anAllCategory[E_SERVICE_POWERCAFE] = query.value(0).toInt();
            }
            break;
        }
        }
    }
    return true;
}

/*
bool SInitializer::initConsumerCategory()
{
    QSqlQuery query(m_sDBManager[SDBManager::E_DATABASE_WEB]);
    int company_num = -1;
    m_nConsumerAllCategory = -1;
    foreach (const stFilterProcess& stfilterprocess, m_listFilterProcess)
    {
        if (stfilterprocess.m_nFilterProcessType == 1)
        {
            QString strQuery = "select statsColumnNum from category where company_num = " +
                    QString::number(stfilterprocess.m_nCompanyNum) + " and num = " + QString::number(stfilterprocess.m_nCategoryNum);
            if (!query.exec(strQuery.toUtf8()))
            {
                insertLog(query.lastQuery());
                insertLog(query.lastError().text());
                return false;
            }
            while (query.next())
            {
                 m_mapConsumerCategory.insert(stfilterprocess.m_nCategoryNum, query.value(0).toInt());
            }
            company_num = stfilterprocess.m_nCompanyNum;
        }
    }
    if (company_num != -1)
    {
        QString strQuery = "select num from category where company_num = " + QString::number(company_num) + " and statsColumnNum = 1";
        if (!query.exec(strQuery.toUtf8()))
        {
            insertLog(query.lastQuery());
            insertLog(query.lastError().text());
            return false;
        }
        while (query.next())
        {
            m_nConsumerAllCategory = query.value(0).toInt();
            m_mapConsumerCategory.insert(m_nConsumerAllCategory ,1);
        }
    }
    return true;
}
*/

int SInitializer::getConsumerAllCategory()
{
    return m_nConsumerAllCategory;
}


const double* SInitializer::getSpammerParam() const
{
    return m_adSpammerParam;
}

bool SInitializer::initColumn()
{
    m_stColumn.m_slColumn.clear();
    for (int i = 0; i < E_DATA_MAX; i++)
        m_stColumn.m_anColumn[i] = -1;

    QVector <QStringList> vecColumn;
    QFile file("column.txt");
    if (file.open(QIODevice::ReadOnly | QIODevice::Text) == false) return false;
    {
        while (!file.atEnd())
        {
            QString str = QString(file.readLine());
            if (str.at(0) == QChar('#')) continue;
            if (str.trimmed().isEmpty()) continue;
            vecColumn.push_back(str.split(","));
        }
    }
    if (vecColumn.size() <= 0) return false;

    foreach (const QStringList& strList,vecColumn)
        m_stColumn.m_slColumn.push_back(strList.at(E_COLUMN_DATABASE));

    for (QStringList::size_type i = 0; i < m_stColumn.m_slColumn.size(); i++)
    {
        if (m_stColumn.m_slColumn[i].trimmed() == QString("platform_title")) m_stColumn.m_anColumn[E_DATA_platform_title] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("article_form"))  m_stColumn.m_anColumn[E_DATA_article_form] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("article_parent"))  m_stColumn.m_anColumn[E_DATA_article_parent] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("article_id"))  m_stColumn.m_anColumn[E_DATA_article_id] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("article_nickname"))  m_stColumn.m_anColumn[E_DATA_article_nickname] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("article_title"))  m_stColumn.m_anColumn[E_DATA_article_title] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("article_data"))  m_stColumn.m_anColumn[E_DATA_article_data] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("article_url"))  m_stColumn.m_anColumn[E_DATA_article_url] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("article_hit"))  m_stColumn.m_anColumn[E_DATA_article_hit] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("article_date"))  m_stColumn.m_anColumn[E_DATA_article_date] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("article_order"))  m_stColumn.m_anColumn[E_DATA_article_order] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("platform_id"))  m_stColumn.m_anColumn[E_DATA_platform_id] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("platform_name"))  m_stColumn.m_anColumn[E_DATA_platform_name] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("platform_form"))  m_stColumn.m_anColumn[E_DATA_platform_form] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("reply_url"))  m_stColumn.m_anColumn[E_DATA_reply_url] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("keyword_id"))  m_stColumn.m_anColumn[E_DATA_keyword_id] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("article_profileurl")) m_stColumn.m_anColumn[E_DATA_article_profileurl] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("article_profile")) m_stColumn.m_anColumn[E_DATA_article_profile] = i;
        if (m_stColumn.m_slColumn[i].trimmed() == QString("etc")) m_stColumn.m_anColumn[E_DATA_etc] = i;
    }
    return true;
}

bool SInitializer::initCompanyNum()
{
    return true;
}

void SInitializer::insertLog(const QString& _strMsg) const
{
    cout << "[";
    cout << m_stFilterProcessGroup.m_strFilterProcessGroupName.toStdString();
    cout << "] ";
    cout << _strMsg.toStdString() << endl;

    QFile file(m_stFilterProcessGroup.m_strFilterProcessGroupName + "." + QDate::currentDate().toString(Qt::ISODate)+".log");
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append))
        return;

    QTextStream out(&file);
    out << QTime::currentTime().toString("[hh:mm:ss] ") << _strMsg << "\n";
    file.close();
}

QSqlDatabase SInitializer::getDatabase(const QString& _dbName) const
{
    return m_sDBManager[_dbName];
}

QSqlDatabase SInitializer::getDatabase(const SDBManager::E_DATABASE& _eDatabase) const
{
    return m_sDBManager[_eDatabase];
}

QStringList SInitializer::getColumnStringList() const
{
    return m_stColumn.m_slColumn;
}

QString SInitializer::getStartDay() const
{
    return m_strStartDay;
}

QString SInitializer::getEndDay() const
{
    return m_strEndDay;
}

const int* SInitializer::getColumnIntArray() const
{
    return m_stColumn.m_anColumn;
}

QList<SInitializer::stFilterProcess> SInitializer::getFilterProcess()
{
    return m_listFilterProcess;
}

QMap<int, QList<SInitializer::stFilter> > SInitializer::getFilterGroup()
{
    return m_mapFilterGroup;
}

bool SInitializer::initPlatform()
{
    QString strQuery;
    strQuery = "select num,form FROM platformform";
    QSqlQuery query(m_sDBManager[SDBManager::E_DATABASE_WEB]);

    if (!query.exec(strQuery.toUtf8()))
    {
        insertLog(query.lastQuery());
        insertLog(query.lastError().text());
        return false;
    }
    while(query.next())
        m_stPlatform.m_mapPlatformForm.insert(query.value(1).toString(),query.value(0).toInt());


    query.clear();
    strQuery = "select num,name FROM platformname";

    if (!query.exec(strQuery.toUtf8()))
    {
        insertLog(query.lastQuery());
        insertLog(query.lastError().text());
        return false;
    }

    while(query.next())
        m_stPlatform.m_mapPlatformName.insert(query.value(1).toString(),query.value(0).toInt());

    return true;
}
QList<SInitializer::stFilter> SInitializer::getFilterGroup(int _nFilterGroupId)
{
    return m_mapFilterGroup[_nFilterGroupId];
}

int SInitializer::getPlatformForm(const QString &_form)
{
    return m_stPlatform.m_mapPlatformForm.value(_form.trimmed(), 1);
}

int SInitializer::getPlatformName(const QString &_name)
{
    return m_stPlatform.m_mapPlatformName.value(_name.trimmed(), 1);
}

QMap<int, int>* SInitializer::getConsumerCategory()
{
    return &m_mapConsumerCategory;
}
double SInitializer::getInfluencerParam(int _BodyorReply)
{
    return m_stInfluencerParam[_BodyorReply];
}

void SInitializer::closeConnection(const SDBManager::E_DATABASE _eDatabase)
{
    m_sDBManager.close(_eDatabase);
}

void SInitializer::closeConnection(const QString& _str)
{
    m_sDBManager.close(_str);
}

bool SInitializer::openConnection(const SDBManager::E_DATABASE _eDatabase)
{
    return m_sDBManager.open(_eDatabase);
}

bool SInitializer::openConnection(const QString& _str)
{
    return m_sDBManager.open(_str);
}

int SInitializer::getAllCategoryNum(int _nService)
{
    return m_anAllCategory[_nService];
}

