1// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2// See LICENSE.txt for license information.
3
4package commands
5
6import (
7	"bytes"
8	"encoding/json"
9	"fmt"
10	"os"
11	"reflect"
12	"sort"
13	"strings"
14
15	"github.com/spf13/cobra"
16
17	"github.com/mattermost/mattermost-server/v6/model"
18)
19
20const CustomDefaultsEnvVar = "MM_CUSTOM_DEFAULTS_PATH"
21
22// printStringMap takes a reflect.Value and prints it out alphabetically based on key values, which must be strings.
23// This is done recursively if it's a map, and uses the given tab settings.
24func printStringMap(value reflect.Value, tabVal int) string {
25	out := &bytes.Buffer{}
26
27	var sortedKeys []string
28	stringToKeyMap := make(map[string]reflect.Value)
29	for _, k := range value.MapKeys() {
30		sortedKeys = append(sortedKeys, k.String())
31		stringToKeyMap[k.String()] = k
32	}
33
34	sort.Strings(sortedKeys)
35
36	for _, keyString := range sortedKeys {
37		key := stringToKeyMap[keyString]
38		val := value.MapIndex(key)
39		if newVal, ok := val.Interface().(map[string]interface{}); !ok {
40			fmt.Fprintf(out, "%s", strings.Repeat("\t", tabVal))
41			fmt.Fprintf(out, "%v: \"%v\"\n", key.Interface(), val.Interface())
42		} else {
43			fmt.Fprintf(out, "%s", strings.Repeat("\t", tabVal))
44			fmt.Fprintf(out, "%v:\n", key.Interface())
45			// going one level in, increase the tab
46			tabVal++
47			fmt.Fprintf(out, "%s", printStringMap(reflect.ValueOf(newVal), tabVal))
48			// coming back one level, decrease the tab
49			tabVal--
50		}
51	}
52
53	return out.String()
54}
55
56func getConfigDSN(command *cobra.Command, env map[string]string) string {
57	configDSN, _ := command.Flags().GetString("config")
58
59	// Config not supplied in flag, check env
60	if configDSN == "" {
61		configDSN = env["MM_CONFIG"]
62	}
63
64	// Config not supplied in env or flag use default
65	if configDSN == "" {
66		configDSN = "config.json"
67	}
68
69	return configDSN
70}
71
72func loadCustomDefaults() (*model.Config, error) {
73	customDefaultsPath := os.Getenv(CustomDefaultsEnvVar)
74	if customDefaultsPath == "" {
75		return nil, nil
76	}
77
78	file, err := os.Open(customDefaultsPath)
79	if err != nil {
80		return nil, fmt.Errorf("unable to open custom defaults file at %q: %w", customDefaultsPath, err)
81	}
82	defer file.Close()
83
84	var customDefaults *model.Config
85	err = json.NewDecoder(file).Decode(&customDefaults)
86	if err != nil {
87		return nil, fmt.Errorf("unable to decode custom defaults configuration: %w", err)
88	}
89
90	return customDefaults, nil
91}
92