package conf

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
)

var (
	ErrReadConfFailed = errors.New("Failed to load config file")
	ErrParseConfJson  = errors.New("Parse json from config file failed")
)

//zookeeper 参数 omitempty
type ZooConf struct {
	Hosts    []string `json:"hosts"` //地址 "ip:port"
	Username string   `json:"username"`
	Password string   `json:"password"`
	Timeout  int      `json:"timeout"` // 超时秒数
}

// 通用的配置参数，每个进程可能只需关注部分值
// agent 所有都需要
// lobby 不需要 代理配置
// manager 不需要代理配置，不需要 rpc 配置
type Conf struct {
	Zoo       ZooConf `json:"zoo"`
	Id        uint64  `json:"id"`        // 进程实例ID
	Namespace string  `json:"namespace"` // 进程空间
	Host      string  `json:"host"`      // 监听地址
	Port      int     `json:"port"`      // 监听端口
	RpcAddr   string  `json:"rpcAddr"`   // rpc 服务地址端口
	ProfAddr  string  `json:"profAddr"`  // pprof addr
	AgHost    string  `json:"agHost"`    // 代理本服务的代理地址 // 代理配置只在 agent 中使用
	AgPort    int     `json:"agPort"`    // 代理端口
	LogPath   string  `json:"logPath"`   // 日志文件路径 default: 当前路径(working dir)
	Level     int     `json:"level"`     // 日志级别
	Online    int     `json:"online"`    // 是否在线(1/0)，用于zookeeper,进程自注册后，可外部改动此值，使当前进程立即孤立，适时退出
	Mode      string  `json:"mode"`      // 运行模式，只对 http 有效
}

func LoadConf(f string) (*Conf, error) {
	bytes, err := ioutil.ReadFile(f)
	if err != nil {
		fmt.Println(err, f)
		return nil, ErrReadConfFailed
	}
	c := &Conf{}
	err = json.Unmarshal(bytes, c)
	if nil != err {
		fmt.Println(err, f)
		return nil, ErrParseConfJson
	}
	return c, nil
}
