package platform

import (
	"errors"
	"os"
	"path/filepath"
	"sort"
	"strings"
)

type DirectoryEntry struct {
	Name string `json:"name"`
	Path string `json:"path"`
}

var browseRoots = []string{"/mnt/user", "/mnt/disks", "/mnt/remotes", "/boot"}

func BrowseDirectories(path string) ([]DirectoryEntry, error) {
	clean, err := validateBrowsePath(path)
	if err != nil {
		return nil, err
	}
	entries, err := os.ReadDir(clean)
	if err != nil {
		return nil, err
	}
	result := make([]DirectoryEntry, 0, len(entries))
	for _, entry := range entries {
		if entry.IsDir() && entry.Type()&os.ModeSymlink == 0 {
			result = append(result, DirectoryEntry{Name: entry.Name(), Path: filepath.Join(clean, entry.Name())})
		}
	}
	sort.Slice(result, func(i, j int) bool { return strings.ToLower(result[i].Name) < strings.ToLower(result[j].Name) })
	return result, nil
}

func BrowseRoots() []DirectoryEntry {
	result := make([]DirectoryEntry, 0, len(browseRoots))
	for _, root := range browseRoots {
		if info, err := os.Stat(root); err == nil && info.IsDir() {
			result = append(result, DirectoryEntry{Name: root, Path: root})
		}
	}
	return result
}

func validateBrowsePath(path string) (string, error) {
	if path == "" || path == "/" {
		return "", errors.New("validation: select an allowed browse root")
	}
	clean := filepath.Clean(path)
	if !filepath.IsAbs(clean) {
		return "", errors.New("validation: browse path must be absolute")
	}
	allowed := false
	for _, root := range browseRoots {
		if clean == root || strings.HasPrefix(clean, root+string(os.PathSeparator)) {
			allowed = true
			break
		}
	}
	if !allowed {
		return "", errors.New("validation: browse path is outside allowed Unraid storage roots")
	}
	resolved, err := filepath.EvalSymlinks(clean)
	if err != nil {
		return "", err
	}
	for _, root := range browseRoots {
		if resolved == root || strings.HasPrefix(resolved, root+string(os.PathSeparator)) {
			return resolved, nil
		}
	}
	return "", errors.New("validation: browse path resolves outside allowed Unraid storage roots")
}
