#pragma once

#ifndef URL_NAME_H_FF631F5BE9244f4685B2EB84ED93BFFF
#define URL_NAME_H_FF631F5BE9244f4685B2EB84ED93BFFF

#include <iostream>
#include <wmconsole/legacy/util/istring.h>
#include <library/cpp/uri/http_url.h>

namespace NWebmaster {
class t_url_name {
    friend bool operator==(const t_url_name &u1, const t_url_name &u2);
    friend bool operator<(const t_url_name &u1, const t_url_name &u2);

public:
    t_url_name() {};
    template <typename t_str1, typename t_str2>
    t_url_name(const t_str1 &host, const t_str2 &url) : host(host.c_str()), url(url.c_str()) {};

    template <typename t_str>
    explicit t_url_name(const t_str &u) {
        t_str x;
        if (strstr(u.c_str(), "://") == 0) {
            x = "http://";    // default scheme
        }
        x += u;

        THttpURL parsed;
        int code = parsed.ParseAbs(x.c_str(),
                                   THttpURL::FeaturesRobot | THttpURL::FeatureUnescapeStandard | THttpURL::FeatureEscSpace | THttpURL::FeatureEscapeUnescaped);

        if (code) {
            return;    // can not parse -- do nothing
        }

        host = parsed.PrintS(THttpURL::FlagScheme | THttpURL::FlagHostPort);
        url = parsed.PrintS(THttpURL::FlagPath | THttpURL::FlagQuery);
    }

    t_url_name(const t_url_name &u) : host(u.host), url(u.url) {};

    const t_url_name &operator=(const t_url_name &u) {
        host = u.host;
        url = u.url;
        return *this;
    }

    operator std::string() const {
        std::string res(host.c_str());
        res += url;
        return res;
    }

    void clear() {
        host.clear();
        url.clear();
    }

    void swap(t_url_name &u) {
        host.swap(u.host);
        url.swap(u.url);
    }

    bool empty() const {
        return (host.empty() && url.empty());
    }

    const istring &get_host() const {
        return host;
    }
    const std::string &get_url() const {
        return url;
    }

    template <typename t_str>
    void set_host(const t_str &h) {
        host = h;
    }

    template <typename t_str>
    void set_url(const t_str &u) {
        url = u;
    }

private:
    istring host;
    std::string url;
};

inline bool operator==(const t_url_name &u1, const t_url_name &u2) {
    if (u1.host != u2.host) {
        return false;
    }
    if (u1.url != u2.url) {
        return false;
    }
    return true;
}

inline bool operator<(const t_url_name &u1, const t_url_name &u2) {
    if (u1.host < u2.host) {
        return true;
    }
    if (u1.host > u2.host) {
        return false;
    }
    return (u1.url < u2.url);
}

inline std::ostream &operator<<(std::ostream &os, const t_url_name &t) {
    return (os << t.get_host() << t.get_url());
}

} //namespace NWebmaster

#endif //URL_NAME_H_FF631F5BE9244f4685B2EB84ED93BFFF
