#ifndef SUPPORT_URL_HPP
#define SUPPORT_URL_HPP

#include "reader/support.hpp"
#include <cstdlib>

class SupUrlCracker {
public:
    SupUrlCracker(const std::string& url) {
	m_correct = false;
	const std::string scheme_separator = "://";
	const size_t scheme_end = url.find(scheme_separator);
	if (scheme_end == std::string::npos)
	    return;
	const size_t host_start = scheme_end + scheme_separator.length();
	const size_t host_end = url.find_first_of(":/",
	    scheme_end + scheme_separator.length());
	if (host_end == std::string::npos)
	    return;
	const size_t port_start = host_end;
	const size_t port_end = url.find('/', host_end);
	const std::string port = url.substr(port_start, port_end - port_start);
	if (port_end == std::string::npos)
	    return;
	const size_t path_start = port_end;

	m_scheme = url.substr(0, host_start);
	m_hostname = url.substr(host_start, host_end - host_start);
	m_port = GetPortNumByStr(port);
	m_fullhostname = m_scheme + m_hostname + port;
	m_path = url.substr(path_start);
	m_correct = true;
    };
    // возвращает схему (https://)
    inline const std::string& GetScheme() const {
	if (!m_correct)
	    throw cpro::CryptoAPIException((DWORD)ERROR_INVALID_PARAMETER);
	return m_scheme;
    }
    // возвращает имя сервера без схемы и без порта
    inline const std::string & GetHostName() const {
	if (!m_correct)
	    throw cpro::CryptoAPIException((DWORD)ERROR_INVALID_PARAMETER);
	return m_hostname;
    }
    // возвращает схему + имя сервера + порт
    inline const std::string & GetFullHostName() const {
	if (!m_correct)
	    throw cpro::CryptoAPIException((DWORD)ERROR_INVALID_PARAMETER);
	return m_fullhostname;
    }
    // возвращает номер порта
    inline int GetPort() const {
	if (!m_correct)
	    throw cpro::CryptoAPIException((DWORD)ERROR_INVALID_PARAMETER);
	return m_port;
    }
    // возвращает URL-путь
    inline const std::string & GetPath() const {
	if (!m_correct)
	    throw cpro::CryptoAPIException((DWORD)ERROR_INVALID_PARAMETER);
	return m_path;
    }
    // проверяет корректность разобранного URL
    // должна вызываться перед получением частей
    inline bool IsCorrectUrl() const {
	return m_correct;
    }

private:
    std::string m_scheme;
    std::string m_hostname;
    int m_port;
    std::string m_fullhostname;
    std::string m_path;
    bool m_correct;

    int GetPortNumByStr(const std::string& port) const {
	static const int DEFAULT_HTTP_PORT = 80;
	static const int DEFAULT_HTTPS_PORT = 443;
	if (port.empty()) {
	    if (m_scheme == "https://") 
		return DEFAULT_HTTPS_PORT;
	    else
		return DEFAULT_HTTP_PORT;
	}
	else
	    return std::atoi((port.substr(1)).c_str());
    }
};

#endif // SUPPORT_URL_HPP
