#include "historydb.h"

#include <QDIR>
#include <QSettings>
#include <QApplication>

#include "mydebug.h"

// cursor pointer used to ensure a single instance of the class.
dbHistory* dbHistory::s_instance = 0;

/* This function is called to create an instance of the class.
 *   Calling the constructor publicly is not allowed. The constructor
 *   is private and is only called by this Instance function.
 */
dbHistory* dbHistory::instance()
{
    // Only allow one instance of class to be generated.
    if (!s_instance)
        s_instance = new dbHistory;
    return s_instance;
}

dbHistory::dbHistory()
{
    history_folder = QApplication::applicationDirPath() + "/" DB_FOLDER_NAME;
    history_filedb = history_folder+'/'+DB_FILE_NAME;
}

//***********************************************************************
// read history from a specific folder
// Input parameters:
// Returns:
//***********************************************************************
bool dbHistory::readHistory()
{
    return true;
}


//***********************************************************************
// add new entry into db file
// Input parameters:        _new = new entry info
// Returns:                 true = ok
//                          false = error
//***********************************************************************
bool dbHistory::addToDB(db_item_t _new)
{
    unsigned int num_entry = listDBEntry.count();
    QSettings settings( history_filedb, QSettings::IniFormat);
    if ( settings.status() == QSettings::NoError )
    {
        //aggiorna il contatore
        settings.beginGroup("general");
        settings.setValue("num_entry", num_entry);
        settings.endGroup();

        QString section = QString("entry%1").arg(num_entry-1);

        settings.beginGroup(section);

        settings.setValue("error",      _new.error);
        settings.setValue("name",       _new.name);
        settings.setValue("path",       _new.path);
        settings.setValue("status",     _new.status);
        settings.setValue("timestamp",  _new.timestamp);
        settings.setValue("where",      _new.where);
        settings.setValue("flash_address",_new.flash_address);
        settings.setValue("srio_conn",  _new.srio_conn);
        settings.setValue("spi",        _new.spi);

        settings.endGroup();

        settings.sync();

        if(settings.status() == QSettings::NoError)
            return true;
    }

    return false;
}


//***********************************************************************
// add new file to history
// Input parameters:
// Returns:
//***********************************************************************
bool dbHistory::addNewFile(QString _file,
                           db_error_t _error,
                           QString _where,
                           db_status_t _status,
                           QString _address,
                           QString _srio,
                           unsigned int _spi)
{
    if (!QDir(history_folder).exists())
    {
        MyDebug.logMsg(type_log_info,
                         origin_msg_history,
                         "History folder not present, create new one.");
        if (!QDir().mkdir(history_folder))
        {
            MyDebug.logMsg(type_log_error,
                             origin_msg_history,
                             QString("ERROR create history folder %1").arg(history_folder));
            return false;
        }
    }

    db_item_t entry_info;

    entry_info.error = _error;
    entry_info.name = QFileInfo(_file).completeBaseName();

    QDir d = QFileInfo(_file).absoluteDir();
    entry_info.path=d.absolutePath();

    entry_info.status           = _status;
    entry_info.timestamp        = QDateTime::currentDateTime().toString("yyyy/MM/dd-hh:mm:ss");
    entry_info.where            = _where;
    entry_info.flash_address    = _address;
    entry_info.srio_conn        = _srio;
    entry_info.spi              = _spi;
    entry_info.errorStr         = "";

    listDBEntry.append(entry_info);

    if (!addToDB(entry_info))
    {
        MyDebug.logMsg(type_log_error,
                         origin_msg_history,
                         QString("ERROR to save new entry %1").arg(entry_info.name));
        return false;
    }

    return true;
}

//***********************************************************************
// add new file to history
// Input parameters:
// Returns:
//***********************************************************************
void dbHistory::setParam(QString _host)
{
    hostname = _host;
}

//***********************************************************************
// refresh list
// Input parameters:
// Returns:
//***********************************************************************
void dbHistory::refreshList()
{
    listDBEntry.clear();

    QSettings settings( history_filedb, QSettings::IniFormat);

    if ( settings.status() == QSettings::NoError )
    {
        settings.beginGroup("general");

        int num_entry = settings.value("num_entry", 0).toInt();

        settings.endGroup();

        if (num_entry!=0)
        {
            QString section;
            for (int i = 0; i<num_entry; i++)
            {
                section = QString("entry%1").arg(i);
                if (settings.childGroups().contains(section))
                {
                    db_item_t entry_info;

                    settings.beginGroup(section);

                    entry_info.error            = db_error_t(settings.value("error", 0).toInt());
                    entry_info.name             = settings.value("name", "").toString();
                    entry_info.path             = settings.value("path", "").toString();
                    entry_info.status           = db_status_t(settings.value("status", "").toInt());
                    entry_info.timestamp        = settings.value("timestamp", "").toString();
                    entry_info.where            = settings.value("where", "").toString();
                    entry_info.flash_address    = settings.value("flash_address", "").toString();
                    entry_info.srio_conn        = settings.value("srio_conn", "").toString();
                    entry_info.spi              = settings.value("spi", 0).toInt();
                    entry_info.errorStr         = settings.value("error_str", "").toString();

                    settings.endGroup();

                    listDBEntry.append(entry_info);
                }
            }
        }
    }
}

//***********************************************************************
// getNumEntry
// Input parameters:
// Returns:             number of entry present into db
//***********************************************************************
int dbHistory::getNumEntry()
{
    return listDBEntry.count();
}


//***********************************************************************
// getEntry
// Input parameters:    idx = index of entry to retrive
// Returns:             entry in position idx
//                      itemZero if idx is wrong
//***********************************************************************
db_item_t dbHistory::getEntry(int idx)
{
    db_item_t itemZero;

    if (idx<listDBEntry.count())
    {
        itemZero = listDBEntry[idx];
    }
    return itemZero;
}

//***********************************************************************
// changeStatus at last entry
// Input parameters:    newStatus
// Returns:             true if ok in change status
//                      false if error in change status
//***********************************************************************
bool dbHistory::changeStatusLast(db_status_t newStatus)
{
    int count = listDBEntry.count();

    if (count==0)
        return false;

    //db_item_t lastItem = listDBEntry[count-1];

    listDBEntry[count-1].status = newStatus;

    return updateEntryOnFile(count-1);
}


//***********************************************************************
// changeError at last entry
// Input parameters:    newError
// Returns:             true if ok in change error
//                      false if error in change error
//***********************************************************************
bool dbHistory::changeErrorLast(db_error_t newError, QString _errorstr)
{
    int count = listDBEntry.count();

    if (count==0)
        return false;

    //db_item_t lastItem = listDBEntry[count-1];

    listDBEntry[count-1].error = newError;
    listDBEntry[count-1].errorStr = _errorstr;

    return updateEntryOnFile(count-1);
}

//***********************************************************************
// update info file of idx entry
// Input parameters:    idx
// Returns:             true if ok
//                      false if error
//***********************************************************************
bool dbHistory::updateEntryOnFile(int idx)
{
    QSettings settings( history_filedb, QSettings::IniFormat);
    if (idx>listDBEntry.count())
        return false;

    db_item_t dbEntry = listDBEntry[idx];

    if ( settings.status() == QSettings::NoError )
    {
        QString section = QString("entry%1").arg(idx);

        settings.beginGroup(section);

        settings.setValue("error",          dbEntry.error);
        settings.setValue("name",           dbEntry.name);
        settings.setValue("path",           dbEntry.path);
        settings.setValue("status",         dbEntry.status);
        settings.setValue("timestamp",      dbEntry.timestamp);
        settings.setValue("where",          dbEntry.where);
        settings.setValue("flash_address",  dbEntry.flash_address);
        settings.setValue("srio_conn",      dbEntry.srio_conn);
        settings.setValue("spi",            dbEntry.spi);
        settings.setValue("error_str",      dbEntry.errorStr);

        settings.endGroup();

        settings.sync();

        if(settings.status() == QSettings::NoError)
            return true;
    }
    else
        return false;
}

//***********************************************************************
// getStatusString
// Input parameters:    _status to convert into string
// Returns:             string description of status
//***********************************************************************
QString dbHistory::getStatusString(db_status_t _status)
{
    switch(_status)
    {
    case db_status_error:
        return db_status_error_str;
        break;
    case db_status_nc:
        return db_status_nc_str;
        break;
    case db_status_started:
        return db_status_started_str;
        break;
    case db_status_erased:
        return db_status_erased_str;
        break;
    case db_status_programmed:
        return db_status_programmed_str;
        break;
    default:
        return db_status_nc_str;
        break;
    }
}

//***********************************************************************
// getErrorString
// Input parameters:    _error to convert into string
// Returns:             string description of error
//***********************************************************************
QString dbHistory::getErrorString(db_error_t _error)
{
    switch(_error)
    {
    case db_error_no_error:
        return db_error_no_error_str;
        break;
    case db_error_format_file:
        return db_error_format_file_str;
        break;
    case db_error_generic:
        return db_error_generic_str;
        break;
    case db_error_erase:
        return db_error_erase_str;
        break;
    case db_error_program:
        return db_error_program_str;
        break;
    case db_error_tftp:
        return db_error_tftp_str;
        break;
    case db_error_srio:
        return db_error_srio_str;
        break;
    default:
        return db_status_nc_str;
        break;
    }
}


//***********************************************************************
// getSPIString
// Input parameters:    _spi to convert into string
// Returns:             string description of spi
//***********************************************************************
QString dbHistory::getSPIString(unsigned int _spi)
{
    switch(_spi)
    {
    case 0:
        return spi_port_primary_str;
        break;
    case 1:
        return spi_port_secondary_str;
        break;
    default:
        return spi_port_primary_str;
        break;
    }
}

//***********************************************************************
// get complete path of history file
// Input parameters:
// Returns:             return path
//***********************************************************************
QString dbHistory::getFileDB()
{
    return history_filedb;
}

//***********************************************************************
// reset history dvìb
// Input parameters:
// Returns:
//***********************************************************************
void dbHistory::reset()
{
    listDBEntry.clear();

    //deletefileDB
    QFile::remove(history_filedb);
}

//***********************************************************************
// save log into filelog in history folder
// Input parameters:
// Returns:
//***********************************************************************
void dbHistory::saveLog()
{

}







