#include <wmconsole/legacy/util/database/database_holder.h>

namespace NWebmaster {

//-----------------------------------------------------------------------------------
TDatabaseHolder &TDatabaseHolder::instance() {
    static TDatabaseHolder g_instance;
    return g_instance;
}

void TDatabaseHolder::init(const std::string &user_db, const std::vector<std::string> &host_db) {
    user_db_conn_str = check_and_get_conn_str(user_db);
    for (const std::string &host_db_str : host_db) {
        host_db_conn_str.push_back(check_and_get_conn_str(host_db_str));
        db_states.push_back(threads::counter());
    }
    temp_session = session();
}

void TDatabaseHolder::init(const TString &user_db, const TVector<TString> &host_db) {
    user_db_conn_str = check_and_get_conn_str(user_db.data());
    for (const TString &host_db_str : host_db) {
        host_db_conn_str.push_back(check_and_get_conn_str(host_db_str.data()));
        db_states.push_back(threads::counter());
    }
    temp_session = session();
}

std::string TDatabaseHolder::check_and_get_conn_str(const std::string &db_str) {
    NWebmaster::MySQLUrl db_url(db_str);
    return db_url.getConnectionString();
}

WMCSession::Ptr TDatabaseHolder::session() const {
    WMCSession::Ptr res(new WMCSession(Poco::Data::MySQL::Connector::KEY, user_db_conn_str, host_db_conn_str));
    return res;
}

size_t TDatabaseHolder::getHostDbCount() const {
    return host_db_conn_str.size();
}

size_t TDatabaseHolder::getHostDbId(const std::string &hostname) const {
    return temp_session->getHostDbId(hostname);
}

void TDatabaseHolder::get_dbs_states_snapshot(std::vector<TDatabaseState> &res) const {
    res.clear();
    TDatabaseState val;
    for (val.db_index = 0; val.db_index < db_states.size(); ++val.db_index) {
        val.count = db_states[val.db_index].get();
        res.push_back(val);
    }
    std::sort(res.begin(), res.end());
}

void TDatabaseHolder::inc_db_state(size_t db_num) {
    ++(db_states[db_num]);
}

void TDatabaseHolder::dec_db_state(size_t db_num) {
    --(db_states[db_num]);
}

TDatabaseStateLocker::TDatabaseStateLocker(size_t db_num) : db_num(db_num) {
    TDatabaseHolder::instance().inc_db_state(db_num);
}

TDatabaseStateLocker::~TDatabaseStateLocker() {
    TDatabaseHolder::instance().dec_db_state(db_num);
}

} //namespace NWebmaster
