1package i18n
2
3import (
4 "os"
5 "strings"
6
7 "github.com/floatpane/matcha/config"
8)
9
10// DetectLanguage determines the language to use based on config and environment.
11func DetectLanguage(cfg *config.Config) string {
12 // 1. Check config first
13 if lang := detectFromConfig(cfg); lang != "" {
14 return normalizeLanguageCode(lang)
15 }
16
17 // 2. Check environment variables
18 if lang := detectFromEnv(); lang != "" {
19 return normalizeLanguageCode(lang)
20 }
21
22 // 3. Default to English
23 return "en"
24}
25
26// detectFromConfig gets language from configuration.
27func detectFromConfig(cfg *config.Config) string {
28 if cfg == nil {
29 return ""
30 }
31 return cfg.GetLanguage()
32}
33
34// detectFromEnv gets language from environment variables.
35func detectFromEnv() string {
36 // Check standard language environment variables
37 for _, envVar := range []string{"LANGUAGE", "LC_ALL", "LC_MESSAGES", "LANG"} {
38 if lang := os.Getenv(envVar); lang != "" {
39 return lang
40 }
41 }
42 return ""
43}
44
45// normalizeLanguageCode converts various language code formats to a standard form.
46// Examples:
47// - "en_US.UTF-8" -> "en"
48// - "en-US" -> "en"
49// - "pt_BR" -> "pt"
50func normalizeLanguageCode(code string) string {
51 if code == "" {
52 return ""
53 }
54
55 // Remove encoding (e.g., ".UTF-8")
56 if idx := strings.Index(code, "."); idx != -1 {
57 code = code[:idx]
58 }
59
60 // Replace underscore with hyphen
61 code = strings.ReplaceAll(code, "_", "-")
62
63 // Split on hyphen and take base language
64 parts := strings.Split(code, "-")
65 if len(parts) > 0 {
66 base := strings.ToLower(parts[0])
67
68 // Validate it's a known language
69 if HasLanguage(base) {
70 return base
71 }
72 }
73
74 return code
75}