package viperx

import (
	"bytes"
	"fmt"
	"os"
	"path/filepath"

	"github.com/spf13/viper"
)

var paths = []string{
	".",
	"./etc",
	"./config",
}

// ConfigFileEncryptorHook 配置文件加密器
type ConfigFileEncryptorHook interface {
	IsCipherText([]byte) bool
	Encrypt([]byte) []byte
	Decrypt([]byte) []byte
}

var configFileEH ConfigFileEncryptorHook

// RegisterConfigEncryptor 注册配置文件加密器
func RegisterConfigEncryptor(h ConfigFileEncryptorHook) {
	configFileEH = h
}

// GetViper 获取viper配置
// name: 配置文件路径和名称，json、yaml、ini等
func GetViper(name string) *viper.Viper {
	buf, err := ReadFile(name)
	if err != nil {
		panic(fmt.Sprintf("Error while reading config file %s: %v", name, err))
	}

	if configFileEH != nil {
		if configFileEH.IsCipherText(buf) {
			buf = configFileEH.Decrypt(buf)
		}
	}

	vp := viper.New()
	ext := filepath.Ext(name)
	if len(ext) > 0 {
		ext = ext[1:] // 去掉点
	}
	vp.SetConfigType(ext)
	if err = vp.ReadConfig(bytes.NewReader(buf)); err != nil {
		panic(fmt.Sprintf("Error while reading config file %s: %v", name, err))
	}
	return vp
}

func ReadFile(name string) ([]byte, error) {
	for _, v := range paths {
		file := filepath.Join(v, name)
		if _, err := os.Stat(file); err == nil {
			return os.ReadFile(file)
		}
	}
	return nil, nil
}
