//go:generate stringer -type=URLPart -trimprefix URL

package format

import (
	"log"
	"strconv"
	"strings"
)

// URLPart is an indicator as to what part of an URL a field is serialized to.
type URLPart int

// Suffix returns the separator between the URLPart and its subsequent part.
func (u URLPart) Suffix() rune {
	switch u {
	case URLQuery:
		return '/'
	case URLUser:
		return ':'
	case URLPassword:
		return '@'
	case URLHost:
		return ':'
	case URLPort:
		return '/'
	case URLPath:
		return '/'
	default:
		return '/'
	}
}

// indicator as to what part of an URL a field is serialized to.
const (
	URLQuery URLPart = iota
	URLUser
	URLPassword
	URLHost
	URLPort
	URLPath // Base path; additional paths are URLPath + N
)

// ParseURLPart returns the URLPart that matches the supplied string.
func ParseURLPart(inputString string) URLPart {
	lowerString := strings.ToLower(inputString)
	switch lowerString {
	case "user":
		return URLUser
	case "pass", "password":
		return URLPassword
	case "host":
		return URLHost
	case "port":
		return URLPort
	case "path", "path1":
		return URLPath
	case "query", "":
		return URLQuery
	}

	// Handle dynamic path segments (e.g., "path2", "path3", etc.).
	if strings.HasPrefix(lowerString, "path") && len(lowerString) > 4 {
		if num, err := strconv.Atoi(lowerString[4:]); err == nil && num >= 2 {
			return URLPath + URLPart(num-1) // Offset from URLPath; "path2" -> URLPath+1
		}
	}

	log.Printf("invalid URLPart: %s, defaulting to URLQuery", lowerString)

	return URLQuery
}

// ParseURLParts returns the URLParts that matches the supplied string.
func ParseURLParts(s string) []URLPart {
	rawParts := strings.Split(s, ",")
	urlParts := make([]URLPart, len(rawParts))

	for i, raw := range rawParts {
		urlParts[i] = ParseURLPart(raw)
	}

	return urlParts
}
