package formats import ( "fmt" "math/rand" "time" ) // FormatPesos defines selection weights for each format. var FormatPesos = map[string]int{ "como": 5, "erro": 2, "porque": 2, "checklist": 1, "comparacao": 1, "bastidor": 1, } // SortearFormato picks a weighted random format, excluding bloqueados. // Uses a fresh rand source seeded with time.Now().UnixNano() per call. func SortearFormato(bloqueados []string) string { r := rand.New(rand.NewSource(time.Now().UnixNano())) blocked := make(map[string]bool, len(bloqueados)) for _, b := range bloqueados { blocked[b] = true } type item struct { formato string peso int } var pool []item total := 0 for formato, peso := range FormatPesos { if !blocked[formato] { pool = append(pool, item{formato, peso}) total += peso } } // Fallback: unblock all when every format is blocked if total == 0 { for formato, peso := range FormatPesos { pool = append(pool, item{formato, peso}) total += peso } } pick := r.Intn(total) acc := 0 for _, it := range pool { acc += it.peso if pick < acc { return it.formato } } return pool[0].formato } // ValidarFormato returns an error if f is not one of the 6 valid formats. func ValidarFormato(f string) error { if _, ok := FormatPesos[f]; ok { return nil } return fmt.Errorf("formato %q inválido — válidos: como, erro, porque, checklist, comparacao, bastidor", f) } // FormatLabel returns the human-readable label for a format. func FormatLabel(f string) string { switch f { case "como": return "Como fazer" case "erro": return "Erro clássico" case "porque": return "Por que" case "checklist": return "Checklist" case "comparacao": return "Comparação" case "bastidor": return "Bastidor" default: return f } }