package services

import (
	"fmt"
	"path/filepath"
	"strings"
)

// SafeResolvePath resolves a user-supplied relative path within a base directory.
// Returns an error if the resolved path escapes the base directory (path traversal).
// The baseDir must be an absolute path.
func SafeResolvePath(baseDir, userInput string) (string, error) {
	if userInput == "" {
		return "", fmt.Errorf("empty path")
	}

	// Reject absolute paths
	if filepath.IsAbs(userInput) {
		return "", fmt.Errorf("absolute paths not allowed")
	}

	// Clean the user input to resolve . and .. components
	cleaned := filepath.Clean(userInput)

	// After cleaning, check if it starts with .. (escapes base)
	if strings.HasPrefix(cleaned, "..") {
		return "", fmt.Errorf("path traversal detected")
	}

	// Resolve the base directory to an absolute path
	absBase, err := filepath.Abs(baseDir)
	if err != nil {
		return "", fmt.Errorf("invalid base directory: %w", err)
	}

	// Join and resolve the full path
	fullPath := filepath.Join(absBase, cleaned)

	// Final containment check: the resolved path must be within the base directory
	absFullPath, err := filepath.Abs(fullPath)
	if err != nil {
		return "", fmt.Errorf("invalid resolved path: %w", err)
	}

	// Ensure the resolved path is strictly inside the base directory (not the base itself)
	if !strings.HasPrefix(absFullPath, absBase+string(filepath.Separator)) {
		return "", fmt.Errorf("path traversal detected")
	}

	return absFullPath, nil
}
