package localization import ( "RenewCMS/internal/domain/language" "regexp" "slices" "strings" ) var socialLocalePattern = regexp.MustCompile(`^([A-Za-z]{2,3})_([A-Za-z]{2})$`) func NormalizeSocialLocale(tag string, social *string) (*string, error) { if social == nil { return nil, nil } parts := socialLocalePattern.FindStringSubmatch(*social) if parts == nil { return nil, ErrInvalidSocialLocale } tagLanguage, _, _ := strings.Cut(tag, "-") if !strings.EqualFold(parts[1], tagLanguage) { return nil, ErrInvalidSocialLocale } normalized := strings.ToLower(parts[1]) + "_" + strings.ToUpper(parts[2]) return &normalized, nil } func SocialLocaleState(row Row) string { if row.SocialLocale != nil { return SocialLocaleSet } if _, region, found := strings.Cut(row.Tag, "-"); found && region != "" { return SocialLocaleDerived } return SocialLocaleNotSet } func EffectiveSocialLocale(row Row) *string { switch SocialLocaleState(row) { case SocialLocaleSet: return row.SocialLocale case SocialLocaleDerived: derived := strings.Replace(row.Tag, "-", "_", 1) return &derived } return nil } func normalizeEntries(entries []Entry) ([]Entry, error) { normalized := make([]Entry, 0, len(entries)) seen := map[string]bool{} for _, entry := range entries { tag, err := language.Normalize(entry.Tag) if err != nil { return nil, err } if seen[tag] { return nil, ErrDuplicateLanguage } seen[tag] = true social, err := NormalizeSocialLocale(tag, entry.SocialLocale) if err != nil { return nil, err } normalized = append(normalized, Entry{Tag: tag, Enabled: entry.Enabled, SocialLocale: social}) } return normalized, nil } func Plan(current []Row, counts map[string]VersionCount, change Change) ([]Row, error) { entries, err := normalizeEntries(change.Languages) if err != nil { return nil, err } if !slices.ContainsFunc(entries, func(entry Entry) bool { return entry.Enabled }) { return nil, ErrNoEnabledLanguage } defaultTag, err := language.Normalize(change.Default) if err != nil || !slices.ContainsFunc(entries, func(entry Entry) bool { return entry.Tag == defaultTag && entry.Enabled }) { return nil, ErrDefaultNotEnabled } confirmed := map[string]bool{} for _, row := range current { confirmed[row.Tag] = row.Confirmed if !slices.ContainsFunc(entries, func(entry Entry) bool { return entry.Tag == row.Tag }) && counts[row.Tag].Total+counts[row.Tag].Trashed > 0 { return nil, ErrLanguageInUse } } next := make([]Row, 0, len(entries)) for _, entry := range entries { isDefault := entry.Tag == defaultTag next = append(next, Row{Tag: entry.Tag, IsDefault: isDefault, Enabled: entry.Enabled, Confirmed: confirmed[entry.Tag] || isDefault, SocialLocale: entry.SocialLocale}) } return next, nil }