#pragma once
#include <string>
#include <utility>
#include <vector>
#include <mw/url.hpp>
/// Kind of one path segment supplied to UrlBuilder.
enum class RouteSegmentKind
{
/// Trusted application route text.
LITERAL,
/// One value encoded as a single path segment.
DYNAMIC,
/// Route-registration placeholder accepted only by requestPath().
PLACEHOLDER
};
/// One trusted literal, encoded value, or route-registration placeholder.
struct RouteSegment
{
/// Interpretation applied to value.
RouteSegmentKind kind;
/// Unencoded segment text or placeholder name.
std::string value;
};
/// Ordered query parameters encoded by UrlBuilder.
using QueryParameters =
std::vector<std::pair<std::string, std::string>>;
/// Build base-aware URLs from trusted literal and encoded dynamic segments.
class UrlBuilder
{
public:
/// Construct a builder from a validated absolute HTTP or HTTPS base URL.
explicit UrlBuilder(mw::URL base_url);
/// Return an absolute URL for the supplied route segments.
std::string absolute(
const std::vector<RouteSegment>& segments,
const QueryParameters& query = {}) const;
/// Append one validated relative path beneath a static-mount prefix.
std::string absoluteFromRelativePath(
const std::vector<RouteSegment>& mount_prefix,
const std::string& relative_path,
const QueryParameters& query = {}) const;
/// Return only the base-prefixed server request path.
std::string requestPath(
const std::vector<RouteSegment>& segments) const;
private:
mw::URL base_url_;
};