package config

import (
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"os"

	"tiup-log-collector/log"
	"tiup-log-collector/utils"
	"tiup-log-collector/web"
)

type Config struct {
	Log log.Config `json:"log"`
	Web web.Config `json:"web"`

	Debug      bool   `json:"-"`
	ConfigFile string `json:"-"`
}

func NewConfig() *Config {
	// Default config
	return &Config{
		Log: log.Config{
			EventLogFile: "event.log",
			AppLogFile:   "app.log",
		},
		Web: web.Config{
			Host: "127.0.0.1",
			Port: "8090",
		},
		Debug: false,
	}
}

func ParseArgs(args []string) (*Config, error) {
	cfg := NewConfig()

	fs := flag.NewFlagSet("tiup-log-collector", flag.ContinueOnError)

	fs.StringVar(&cfg.ConfigFile, "c", "", "Specify config file.")
	fs.BoolVar(&cfg.Debug, "debug", false, "Debug mode")

	printHelp := fs.Bool("h", false, "Show this message and exit.")
	echoDemoConfig := fs.Bool("echo_conf", false, "Echo example config")

	fs.SetOutput(os.Stdout)

	fs.Usage = func() {
		_, _ = fmt.Fprintf(fs.Output(), `Version: 1.0.0
Usage: [-c config] [-debug] [-echo_conf] [-h]

Options:
`)
		fs.PrintDefaults()
	}

	if err := fs.Parse(args); err != nil {
		_, _ = fmt.Fprintln(os.Stderr, "Failed to parse command flags: ", err.Error())
		return nil, err
	}

	if *printHelp {
		fs.Usage()
		return nil, flag.ErrHelp
	}

	if *echoDemoConfig {
		printDefaultConfigs()
		return nil, flag.ErrHelp
	}

	if err := cfg.load(); err != nil {
		return nil, err
	}

	return cfg, nil
}

func (cfg *Config) load() error {
	if cfg.ConfigFile == "" {
		_, _ = fmt.Fprintln(os.Stderr, "Please specify config file. use -h for help")
		return errors.New("config file not specified")
	}

	data, err := ioutil.ReadFile(cfg.ConfigFile)
	if err != nil {
		return err
	}

	err = json.Unmarshal(data, cfg)
	if err != nil {
		return err
	}

	return nil
}

func printDefaultConfigs() {
	cfg := NewConfig()
	demoConfig, _ := json.Marshal(cfg)
	_, _ = fmt.Fprintf(os.Stdout, utils.String(demoConfig))
}
