package factgiver import ( "fmt" "math/rand" "regexp" "strings" "time" "github.com/SayaAndy/saya-today-web/config" "github.com/SayaAndy/saya-today-web/internal/blog" ) type FactGiver struct { blogClient blog.Client cache map[string][]string langs []config.AvailableLanguageConfig factsFileName string nlRe *regexp.Regexp randGen *rand.Rand } func NewFactGiver(cfg *config.FactGiverConfig, langs []config.AvailableLanguageConfig) (*FactGiver, error) { blogClient, err := blog.NewClientMap[cfg.Storage.Type](&cfg.Storage) if err != nil { return nil, fmt.Errorf("fail to init b2 client for a new fact giver: %s", err.Error()) } factGiver := &FactGiver{ blogClient: blogClient, cache: make(map[string][]string, len(langs)), langs: langs, factsFileName: cfg.FactsFileName, nlRe: regexp.MustCompile(`\r?\n`), randGen: rand.New(rand.NewSource(time.Now().UnixNano())), } if err = factGiver.initCache(); err != nil { return nil, fmt.Errorf("fail to init cache for a new fact giver: %s", err.Error()) } return factGiver, nil } func (g *FactGiver) Give(lang string) [3]string { factSlice := make([]string, len(g.cache[lang])) copy(factSlice, g.cache[lang]) g.randGen.Shuffle(len(factSlice), func(i, j int) { factSlice[i], factSlice[j] = factSlice[j], factSlice[i] }) return [3]string{factSlice[0], factSlice[1], factSlice[2]} } func (g *FactGiver) initCache() error { for _, lang := range g.langs { localFacts := strings.Replace(g.factsFileName, "*", lang.Name, 1) factsContentBytes, err := g.blogClient.ReadAll(localFacts) if err != nil { return fmt.Errorf("fail to read '%s' facts file: %s", lang.Name, err.Error()) } factsContent := string(factsContentBytes) g.cache[lang.Name] = g.nlRe.Split(factsContent, -1) if g.cache[lang.Name][len(g.cache[lang.Name])-1] == "" { g.cache[lang.Name] = g.cache[lang.Name][:len(g.cache[lang.Name])-1] } } return nil }