package mfer

import (
	"net/url"
	"strings"
)

// ManifestURL represents a URL pointing to a manifest file.
type ManifestURL string

// FileURL represents a URL pointing to a file to be fetched.
type FileURL string

// BaseURL represents a base URL for constructing file URLs.
type BaseURL string

// JoinPath safely joins a relative file path to a base URL.
// The path is properly URL-encoded to prevent path traversal.
func (b BaseURL) JoinPath(path RelFilePath) (FileURL, error) {
	base, err := url.Parse(string(b))
	if err != nil {
		return "", err
	}

	// Ensure base path ends with /
	if !strings.HasSuffix(base.Path, "/") {
		base.Path += "/"
	}

	// Parse and encode the relative path
	ref, err := url.Parse(url.PathEscape(string(path)))
	if err != nil {
		return "", err
	}

	resolved := base.ResolveReference(ref)
	return FileURL(resolved.String()), nil
}

// String returns the URL as a string.
func (b BaseURL) String() string {
	return string(b)
}

// String returns the URL as a string.
func (f FileURL) String() string {
	return string(f)
}

// String returns the URL as a string.
func (m ManifestURL) String() string {
	return string(m)
}
