#include <vector>
#include <sstream>
#include <Poco/Exception.h>
#include <Poco/NumberParser.h>

#include "mysql_url.h"

namespace NWebmaster {

MySQLUrl::MySQLUrl(const std::string &url) {
    std::string::size_type slashPos = url.find_last_of('/');

    if (slashPos == std::string::npos || slashPos >= url.size() - 1) {
        WMCLOG_ERROR(logger(), "MySQL url does not contain database part! " << url);
        throw Poco::InvalidArgumentException("MySQL url does not contain database part!");
    }

    fName = url.substr(slashPos + 1);
    std::string::size_type atPos = url.find_last_of('@');

    if (atPos > slashPos) {
        WMCLOG_ERROR(logger(), "MySQL url does not contain host[:port] part! " << url);
        throw Poco::InvalidArgumentException("MySQL url does not contain host[:port] part!");
    }

    if (atPos == 0) {
        WMCLOG_ERROR(logger(), "MySQL url does not contain user[:password] part! " << url);
        throw Poco::InvalidArgumentException("MySQL url does not contain user[:password] part!");
    }

    std::string hostAndPort = url.substr(atPos + 1, slashPos - atPos - 1);
    std::string::size_type colonPos = hostAndPort.find_first_of(':');

    if (colonPos != std::string::npos) {
        fHost = hostAndPort.substr(0, colonPos);
        fPort = Poco::NumberParser::parseUnsigned(hostAndPort.substr(colonPos + 1));
    } else {
        fHost = hostAndPort;
        fPort = 3306;
    }

    std::string userAndPassword = url.substr(0, atPos);

    colonPos = userAndPassword.find_first_of(':');

    if (colonPos != std::string::npos) {
        fUser = userAndPassword.substr(0, colonPos);
        fPassword = userAndPassword.substr(colonPos + 1);
    } else {
        fUser = userAndPassword;
        fPassword = "";
    }

    std::ostringstream os;
    os << "user=" << fUser << ";";
    os << "password=" << fPassword << ";";
    os << "db=" << fName << ";";
    os << "port=" << fPort << ";";
    os << "host=" << fHost << ";";
    os << "auto-reconnect=true";
    fConnectionString = os.str();

    std::ostringstream os2;
    os2 << "-h " << fHost << " -P " << fPort << " -A " << fName << " -u " << fUser;

    if (!fPassword.empty()) {
        os2 << " -p " << fPassword;
    }

    fCommandlineString = os2.str();
}

} // namespace NWebmaster

