#include "providerdblms.h"

#include <QThread>
#include <QMessageBox>

ProviderDBLMS::ProviderDBLMS(QWidget *parentWidget, QObject *parent) :
    QObject(parent),
    dbLMS(nullptr),
    parentWidget(parentWidget)
{
    dbLMS = new InterfaceDataBaseLMS(parentWidget);
    connect(dbLMS, &InterfaceDataBaseLMS::signal_ErrorPostgreSQL, this, &ProviderDBLMS::signal_ErrorPostgreSQL);
}

ProviderDBLMS::~ProviderDBLMS()
{
    DisConnectionFromDB();
}

bool ProviderDBLMS::ConnectionToDB()
{
   mtxAccess.lock();
   if(! dbLMS->DBisConnected())
   {
       if(dbLMS->connectionToDB())
       {
           Q_EMIT signal_BlockAutorization(false);

           mtxAccess.unlock();
           return  true;
       }
       else
       {
           mtxAccess.unlock();
           return false;
       }
   }
   mtxAccess.unlock();
   return true;
}

void ProviderDBLMS::DisConnectionFromDB()
{
    mtxAccess.lock();
    if(dbLMS->DBisConnected())
    {
        Q_EMIT signal_BlockAutorization(true);

        dbLMS->disConnectionFromDB();
    }
    mtxAccess.unlock();
}

bool ProviderDBLMS::DBisConnected()
{
    bool res = false;
    mtxAccess.lock();
    res = dbLMS->DBisConnected();
    mtxAccess.unlock();
    return res;
}

DataBaseSettings ProviderDBLMS::getDBSettings()
{
    return dbLMS->getDataBaseSettings();
}

bool ProviderDBLMS::setUserPasswordPostgres(QString userName, QString password)
{
    return dbLMS->setUserPasswordPostgres(userName, password);
}

bool ProviderDBLMS::checkDriverQPSQLavailable()
{
    return dbLMS->checkDriverQPSQLavailable();
}

bool ProviderDBLMS::checkUserLMSexist()
{
    return dbLMS->checkUserLMSexist();
}

bool ProviderDBLMS::checkDataBaseLMSexist()
{
    return dbLMS->checkDataBaseLMSexist();
}

bool ProviderDBLMS::createUser()
{
    return dbLMS->createUser();
}

bool ProviderDBLMS::createDB()
{
    return dbLMS->createDB();
}

QString ProviderDBLMS::getMainInstructorName()
{
    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return QStringLiteral("");
    }
    mtxAccess.unlock();
    return QStringLiteral("");
}

bool ProviderDBLMS::authorizationTrainee(QString login, QString password, QString classroom_name, QString computer_name)
{
    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return false;
    }

    //Q_EMIT signal_BlockAutorization(true);

    bool res = dbLMS->authorizationTrainee(login, password, classroom_name, computer_name);

    //Q_EMIT signal_BlockAutorization(false);

     mtxAccess.unlock();
     return res;
}

bool ProviderDBLMS::deAuthorizationTrainee(QString login)
{
    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return false;
    }

    //Q_EMIT signal_BlockAutorization(true);

    bool res = dbLMS->deAuthorizationTrainee(login);

    //Q_EMIT signal_BlockAutorization(false);

    mtxAccess.unlock();
    return res;
}

QString ProviderDBLMS::getNameTraineeByLogin(QString login)
{
    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return QStringLiteral("");
    }

    QString res =  dbLMS->getNameTraineeByLogin(login);

    mtxAccess.unlock();
    return res;
}

bool ProviderDBLMS::authorizationInstructor(QString login, QString password)
{
    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return false;
    }

    //Q_EMIT signal_BlockAutorization(true);

    bool res = dbLMS->authorizationInstructor(login, password);

    //Q_EMIT signal_BlockAutorization(false);

    mtxAccess.unlock();
    return res;
}

bool ProviderDBLMS::deAuthorizationInstructor(QString login)
{
    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return false;
    }

    //Q_EMIT signal_BlockAutorization(true);

    bool res = dbLMS->deAuthorizationInstructor(login);

    //Q_EMIT signal_BlockAutorization(false);

    mtxAccess.unlock();
    return res;
}

QString ProviderDBLMS::getNameInstructorByLogin(QString login)
{
    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return QStringLiteral("");
    }

    QString res = dbLMS->getNameInstructorByLogin(login);

    mtxAccess.unlock();
    return res;
}

bool ProviderDBLMS::deAuthorizationAll()
{
    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return false;
    }

    Q_EMIT signal_BlockAutorization(true);

    bool res1 = dbLMS->deAuthorizationAllTrainees();
    bool res2 = dbLMS->deAuthorizationAllInstructors();

    Q_EMIT signal_BlockAutorization(false);

    mtxAccess.unlock();
    return res1 && res2;
}

bool ProviderDBLMS::entryTraineeOnSimulator(int id_trainee)
{
    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return false;
    }

    if(dbLMS->entryTraineeOnSimulator(id_trainee))
    {
        mtxAccess.unlock();
        return true;
    }
    else
    {
        mtxAccess.unlock();
        return false;
    }
}

bool ProviderDBLMS::exitTraineeFromSimulator(int id_trainee)
{
    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return false;
    }

    if(dbLMS->exitTraineeFromSimulator(id_trainee))
    {
        mtxAccess.unlock();
        return true;
    }
    else
    {
        mtxAccess.unlock();
        return false;
    }
}

int ProviderDBLMS::getIdTraineeByLogin(QString login)
{
    int id_trainee = 0;

    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return id_trainee;
    }

    id_trainee = dbLMS->getIdTraineeByLogin(login);

    mtxAccess.unlock();
    return id_trainee;
}

int ProviderDBLMS::getIdInstructorByLogin(QString login)
{
    int id_instructor = 0;

    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return id_instructor;
    }

    id_instructor = dbLMS->getIdInstructorByLogin(login);

    mtxAccess.unlock();
    return id_instructor;
}

QString ProviderDBLMS::getLoginTraineeById(int id_trainee)
{
    QString login = "";

    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return login;
    }

    login = dbLMS->getTrainee(id_trainee).getLogin();

    mtxAccess.unlock();
    return login;
}

QList<Instructor> ProviderDBLMS::GetListAllInstructors()
{
    QList<Instructor> listInstructors;

    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return listInstructors;
    }

    listInstructors = dbLMS->getListInstructors();

    mtxAccess.unlock();
    return listInstructors;
}

QList<Trainee> ProviderDBLMS::GetListAllTrainees()
{
    QList<Trainee> listTrainees;

    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return listTrainees;
    }

    listTrainees = dbLMS->getListTrainees();

    mtxAccess.unlock();
    return listTrainees;
}

QList<Group> ProviderDBLMS::GetListAllGroups()
{
    QList<Group> listGroups;

    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return listGroups;
    }

    listGroups = dbLMS->getListGroups();

    mtxAccess.unlock();
    return listGroups;
}

int ProviderDBLMS::newInstructor()
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->newInstructor();
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::delInstructor(int id)
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->delInstructor(id);
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::editInstructor(Instructor instructor)
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->editInstructor(instructor);
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::newTrainee(int id_group)
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->newTrainee(id_group);
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::delTrainee(int id)
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->delTrainee(id);
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::editTrainee(Trainee trainee)
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->editTrainee(trainee);
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::newGroup()
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->newGroup();
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::delGroup(int id)
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->delGroup(id);
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::editGroup(Group group)
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->editGroup(group);
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::newTaskAMM(TaskAmmFim task, int id_trainee)
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->newTaskAMM(task, id_trainee);
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::delTaskAMM(int id)
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->delTaskAMM(id);
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::editTaskAMM(TaskAmmFim task)
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->editTaskAMM(task);
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::newTaskFIM(TaskAmmFim task, int id_trainee)
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->newTaskFIM(task, id_trainee);
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::delTaskFIM(int id)
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->delTaskFIM(id);
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::editTaskFIM(TaskAmmFim task)
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->editTaskFIM(task);
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::replaceReportFIM(TaskAmmFim task)
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->replaceReportFIM(task);
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::changeStatusTaskFIM(int id_task, QString status)
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->changeStatusTaskFIM(id_task, status);
    mtxAccess.unlock();
    return res;
}

int ProviderDBLMS::changeStatusTaskAMM(int id_task, QString status)
{
    int res = 0;
    mtxAccess.lock();
    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return res;
    }
    res = dbLMS->changeStatusTaskAMM(id_task, status);
    mtxAccess.unlock();
    return res;
}

QList<TaskAmmFim> ProviderDBLMS::GetListTasksAMMofTrainee(int id_trainee)
{
    QList<TaskAmmFim> listTasks;

    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return listTasks;
    }

    listTasks = dbLMS->getListTasksAMMofTrainee(id_trainee);

    mtxAccess.unlock();
    return listTasks;
}

QList<TaskAmmFim> ProviderDBLMS::GetListTasksFIMofTrainee(int id_trainee)
{
    QList<TaskAmmFim> listTasks;

    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return listTasks;
    }

    listTasks = dbLMS->getListTasksFIMofTrainee(id_trainee);

    mtxAccess.unlock();
    return listTasks;
}

TaskAmmFim ProviderDBLMS::getTaskAMMbyID(int id_task)
{
    TaskAmmFim task;

    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return task;
    }

    task = dbLMS->getTaskAMMbyID(id_task);

    mtxAccess.unlock();
    return task;
}

TaskAmmFim ProviderDBLMS::getTaskFIMbyID(int id_task)
{
    TaskAmmFim task;

    mtxAccess.lock();

    if(! dbLMS->DBisConnected())
    {
        mtxAccess.unlock();
        return task;
    }

    task = dbLMS->getTaskFIMbyID(id_task);

    mtxAccess.unlock();
    return task;
}
