// Package config handles loading the config.
package config

import (
	"flag"
	"fmt"
	"os"

	"gopkg.in/yaml.v3"
)

var Default *Mod

type Cmd struct {
	Binary    string
	Arguments []string
}

type Config struct {
	HomeName     string `yaml:"home"`
	CameraName   string `yaml:"name"`
	H264Cmd      *Cmd   `yaml:"h264"`
	IVFCmd       *Cmd   `yaml:"ivf"`
	SensorCmd    *Cmd   `yaml:"sensor"`
	SensorRateMS int64  `yaml:"sensor_rate_ms"`
}

func New(source []byte, name string) (*Config, error) {
	config := &Config{}
	if err := yaml.Unmarshal(source, config); err != nil {
		return nil, fmt.Errorf("failed to parse config: %w", err)
	}
	config.CameraName = name
	return config, nil
}

type Mod struct {
	filePath string
	namePath string
}

func (m *Mod) RegisterFlags(fs *flag.FlagSet) {
	fs.StringVar(&m.filePath, "watcher_config", "", "path to the watcher configuration")
	fs.StringVar(&m.namePath, "watcher_name", "/var/lib/dbus/machine-id", "location of the file to pull name from")
}

func (m *Mod) Get() (*Config, error) {
	bytes, err := os.ReadFile(m.filePath)
	if err != nil {
		return nil, fmt.Errorf("failed to read file %q: %w", m.filePath, err)
	}

	// Override name using a unique ID; we can let users name things in the app
	myID, err := os.ReadFile(m.namePath)
	if err != nil {
		return nil, fmt.Errorf("failed to read machine ID from %q", m.namePath)
	}

	config, err := New(bytes, string(myID))
	if err != nil {
		return nil, err
	}

	return config, nil
}

func init() {
	Default = &Mod{}
	Default.RegisterFlags(flag.CommandLine)
}
