package limpeza

import (
	"os"
	"path/filepath"
	"strings"
	"unicode"
)

// RemoverXmlOrfaos apaga .xml e .xml.tmp cujo hash não está em validos (feeds ativos).
// Só remove nomes que parecem hash de feed; ignora .htaccess e outros arquivos.
func RemoverXmlOrfaos(dir string, validos map[string]struct{}) (int, error) {
	dir = filepath.Clean(dir)
	entries, err := os.ReadDir(dir)
	if err != nil {
		if os.IsNotExist(err) {
			return 0, nil
		}
		return 0, err
	}
	n := 0
	for _, e := range entries {
		if e.IsDir() {
			continue
		}
		hash, ok := hashDeNomeArquivo(e.Name())
		if !ok {
			continue
		}
		if _, existe := validos[hash]; existe {
			continue
		}
		if err := os.Remove(filepath.Join(dir, e.Name())); err != nil {
			return n, err
		}
		n++
	}
	return n, nil
}

func hashDeNomeArquivo(name string) (string, bool) {
	lower := strings.ToLower(name)
	var base string
	switch {
	case strings.HasSuffix(lower, ".xml.tmp"):
		base = name[:len(name)-len(".xml.tmp")]
	case strings.HasSuffix(lower, ".xml"):
		base = name[:len(name)-len(".xml")]
	default:
		return "", false
	}
	if !hashPareceFeed(base) {
		return "", false
	}
	return base, true
}

func hashPareceFeed(hash string) bool {
	if len(hash) < 8 || len(hash) > 255 {
		return false
	}
	for _, r := range hash {
		if r > 127 {
			return false
		}
		if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '-' || r == '_' {
			continue
		}
		return false
	}
	return true
}

// ConjuntoHashes monta o set de hashes válidos a partir da lista de feeds.
func ConjuntoHashes(hashes []string) map[string]struct{} {
	m := make(map[string]struct{}, len(hashes))
	for _, h := range hashes {
		h = strings.TrimSpace(h)
		if h == "" {
			continue
		}
		m[h] = struct{}{}
	}
	return m
}
