package config

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"os"
	"strings"

	"gopkg.in/yaml.v3"
)

const defaultLogFile = "termstream.log"

// Destination holds the configuration for a destination.
type Destination struct {
	URL string `yaml:"url"`
}

// Config holds the configuration for the application.
type Config struct {
	LogFile      string        `yaml:"logfile"`
	Destinations []Destination `yaml:"destinations"`
}

// FromFile returns a reader for the default configuration file.
func FromFile() io.Reader {
	r, err := os.Open("config.yml")
	if err != nil {
		return bytes.NewReader([]byte{})
	}

	return r
}

// Default returns a reader for the default configuration.
func Default() io.Reader {
	return bytes.NewReader([]byte(nil))
}

// Load loads the configuration from the given reader.
//
// Passing an empty reader will load the default configuration.
func Load(r io.Reader) (cfg Config, _ error) {
	filePayload, err := io.ReadAll(r)
	if err != nil {
		return cfg, fmt.Errorf("read file: %w", err)
	}

	if err = yaml.Unmarshal(filePayload, &cfg); err != nil {
		return cfg, fmt.Errorf("unmarshal: %w", err)
	}

	setDefaults(&cfg)

	if err = validate(cfg); err != nil {
		return cfg, err
	}

	return cfg, nil
}

func setDefaults(cfg *Config) {
	if cfg.LogFile == "" {
		cfg.LogFile = defaultLogFile
	}
}

func validate(cfg Config) error {
	var err error

	for _, dest := range cfg.Destinations {
		if !strings.HasPrefix(dest.URL, "rtmp://") {
			err = errors.Join(err, fmt.Errorf("destination URL must start with rtmp://"))
		}
	}

	return err
}