package proxy

import (
	"encoding/json"
	"fmt"
	"os"
	"regexp"
)

// PathPattern defines a regex and its replacement for sanitizing URL paths.
type PathPattern struct {
	Name        string `json:"name"`
	Regexp      string `json:"regexp"`
	Replacement string `json:"replacement"`
	compiled    *regexp.Regexp
}

// PathPatterns is a collection of PathPattern.
type PathPatterns []PathPattern

// LoadPatterns loads path patterns from a JSON file.
func LoadPatterns(path string) (PathPatterns, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		if os.IsNotExist(err) {
			return PathPatterns{}, nil
		}

		return nil, err
	}

	var patterns PathPatterns
	if err := json.Unmarshal(data, &patterns); err != nil {
		return nil, err
	}

	for i := range patterns {
		re, err := regexp.Compile(patterns[i].Regexp)
		if err != nil {
			return nil, fmt.Errorf("invalid regex in pattern %s: %w", patterns[i].Name, err)
		}

		patterns[i].compiled = re
	}

	return patterns, nil
}

// Sanitize sanitizes a segment using the configured patterns.
func (pp PathPatterns) Sanitize(segment string) (string, string) {
	for _, p := range pp {
		if p.compiled != nil && p.compiled.MatchString(segment) {
			return p.Replacement, p.Replacement
		}
	}

	return segment, ""
}

// DefaultPatterns returns the default set of path patterns.
func DefaultPatterns() PathPatterns {
	return PathPatterns{
		{
			Name:        "IPv4",
			Regexp:      `^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$`,
			Replacement: "{ip}",
		},
		{
			Name:        "UUID",
			Regexp:      `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`,
			Replacement: "{uuid}",
		},
		{
			Name:        "AccountID",
			Regexp:      `^\d{5,10}$`,
			Replacement: "{accountId}",
		},
		{
			Name:        "DeviceID",
			Regexp:      `^[0-9a-fA-F]{12}$`,
			Replacement: "{device_id}",
		},
	}
}
