package main

import (
	"crypto/tls"
	"errors"
	"fmt"
	"log"
	"os"

	"flag"
	"github.com/go-irc/irc"

	"git.circuitco.de/self/watbot/wat"
	"github.com/creasty/defaults"
	"gopkg.in/yaml.v3"
)

type Config struct {
	Watbot		watConfig	`yaml:"watbot"`
}

type watConfig struct {
	Nick		string		`yaml:"nick"`
	Pass		string		`yaml:"pass"`
	User		string		`yaml:"user"`
	Name		string		`yaml:"name"`
	Admins		struct {
		Hosts []string		`yaml:"hosts"`
	}				`yaml:"admins"`
	Channels 	struct {
		Join      []string	`yaml:"join"`
		Permitted []string	`yaml:"permitted"`
	}				`yaml:"channels"`
	Ignores struct {
		Hosts []string		`yaml:"hosts"`
	}				`yaml:"ignores"`
	Server struct {
		Host string		`yaml:"host"`
		Port int		`default:"6697" yaml:"port"`
		TlsVerify bool		`default:"true" yaml:"tls_verify"`
	}				`yaml:"server"`
}

func readConfig(configPath string) (*watConfig, error) {
	allConfig := Config{}

	buffer, err := os.ReadFile(configPath)
	if err != nil {
		return nil, fmt.Errorf("Could not read configuration file: %s", err)
	}

	err = yaml.Unmarshal(buffer, &allConfig)
	if err != nil {
		return nil, fmt.Errorf("Could not parse configuration file: %s", err)
	}

	config := &allConfig.Watbot
	defaults.Set(config)

	if config.Server.Host == "" {
		return nil, errors.New("Shall I play wattery to know where to connect to?")
	}

	if config.Name != "" && config.Nick == "" {
		config.Nick = config.Name
	}
	
	if config.Nick != "" && config.User == "" {
		config.User = config.Nick
	}

	if config.Name == "" || config.Nick == "" || config.User == "" {
		return nil, errors.New("Don't know who I am.")
	}

	return config, nil
}

func main() {
	var configPathArg string
	flag.StringVar(&configPathArg, "config", "config.yaml", "Path to configuration file")
	flag.Parse()
	log.Println("Starting with configuration:", configPathArg)

	config, err := readConfig(configPathArg)
	if err != nil {
		log.Fatalln(err)
		os.Exit(1)
	}

	ircConfig := irc.ClientConfig{
		Nick: config.Nick,
		Pass: config.Pass,
		User: config.User,
		Name: config.Name,
	}
	watConfig := wat.WatConfig{
		AutoJoinChannels:  config.Channels.Join,
		PermittedChannels: config.Channels.Permitted,
		IgnoredHosts:      config.Ignores.Hosts,
		AdminHosts:        config.Admins.Hosts,
	}
	tcpConf := &tls.Config{
		InsecureSkipVerify: !config.Server.TlsVerify,
	}
	conn, err := tls.Dial("tcp", fmt.Sprintf("%s:%d", config.Server.Host, config.Server.Port), tcpConf)
	if err != nil {
		fmt.Println("err " + err.Error())
		return
	}
	wwat := wat.NewWatBot(&ircConfig, &watConfig, conn)
	wwat.Run()
}
