summaryrefslogtreecommitdiffci
path: root/internal/factgiver/factgiver.go
blob: 6f77403c87bad75a817edfe90e6e41ef25e610c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package factgiver

import (
	"fmt"
	"math/rand"
	"regexp"
	"strings"
	"time"

	"github.com/SayaAndy/saya-today-web/config"
	"github.com/SayaAndy/saya-today-web/internal/b2"
)

type FactGiver struct {
	b2Client      *b2.B2Client
	cache         map[string][]string
	langs         []string
	factsFileName string
	nlRe          *regexp.Regexp
	randGen       *rand.Rand
}

func NewFactGiver(cfg *config.FactGiverConfig, langs []string) (*FactGiver, error) {
	b2Client, err := b2.NewB2Client(&cfg.Storage.Config)
	if err != nil {
		return nil, fmt.Errorf("fail to init b2 client for a new fact giver: %s", err.Error())
	}

	factGiver := &FactGiver{
		b2Client:      b2Client,
		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, 1)
		factsContentBytes, err := g.b2Client.ReadAll(localFacts)
		if err != nil {
			return fmt.Errorf("fail to read '%s' facts file: %s", lang, err.Error())
		}
		factsContent := string(factsContentBytes)
		g.cache[lang] = g.nlRe.Split(factsContent, -1)
		if g.cache[lang][len(g.cache[lang])-1] == "" {
			g.cache[lang] = g.cache[lang][:len(g.cache[lang])-1]
		}
	}
	return nil
}