// Copyright 2025 WIT.COM Inc Licensed GPL 3.0

package tree

// functions to import and export the protobuf
// data to and from config files

import (
	"errors"
	"fmt"
	"os"
	"path/filepath"

	"go.wit.com/log"
)

// load the ~/.config/forge/ files
func configLoad() *ToolkitConfigs {
	if os.Getenv("FORGE_CONFIG") == "" {
		homeDir, _ := os.UserHomeDir()
		fullpath := filepath.Join(homeDir, ".config/forge")
		os.Setenv("FORGE_CONFIG", fullpath)
	}

	c, err := loadText()
	if err != nil {
		log.Info("gui toolkit configLoad() error", err)
	}
	if c != nil {
		return c
	}

	// first time user. make a template config file
	c = sampleConfig()
	return c
}

// makes a sample config (and saves it)
func sampleConfig() *ToolkitConfigs {
	all := NewToolkitConfigs()
	new1 := new(ToolkitConfig)
	new1.Plugin = "tree"
	new1.Name = "test"
	new1.Value = "apple"
	all.Append(new1)

	all.configSave()

	fmt.Println("first time user. adding an example config file with", len(all.ToolkitConfigs), "repos")
	return all
}

// write to ~/.config/forge/ unless ENV{FORGE_CONFIG} is set
func (c *ToolkitConfigs) configSave() error {
	s := c.FormatTEXT()
	configWrite("toolkit.text", []byte(s))
	return nil
}

func loadText() (*ToolkitConfigs, error) {
	// this lets the user hand edit the config
	data, err := loadFile("toolkit.text")
	if err != nil {
		return nil, err
	}
	if data == nil {
		return nil, fmt.Errorf("toolkit.text data was nil")
	}
	if len(data) == 0 {
		return nil, fmt.Errorf("toolkit.text was empty")
	}

	c := new(ToolkitConfigs)

	// attempt to marshal toolkit.text
	if err := c.UnmarshalTEXT(data); err != nil {
		return nil, err
	}
	log.Log(TREE, "ConfigLoad()", len(c.ToolkitConfigs), "entries in ~/.config/forge")
	return c, nil
}

func loadFile(filename string) ([]byte, error) {
	fullname := filepath.Join(os.Getenv("FORGE_CONFIG"), filename)
	data, err := os.ReadFile(fullname)
	if errors.Is(err, os.ErrNotExist) {
		// if file does not exist, just return nil. this
		// will cause ConfigLoad() to try the next config file like "toolkit.text"
		// because the user might want to edit the .config by hand
		return nil, nil
	}
	if err != nil {
		// log.Info("open config file :", err)
		return nil, err
	}
	return data, nil
}

func configWrite(filename string, data []byte) error {
	fullname := filepath.Join(os.Getenv("FORGE_CONFIG"), filename)

	cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
	defer cfgfile.Close()
	if err != nil {
		log.Warn("open config file :", err)
		return err
	}
	if filename == "toolkit.text" {
		// add header
		cfgfile.Write([]byte("\n"))
		cfgfile.Write([]byte("# you can customize your GUI toolkit user settings here\n"))
		cfgfile.Write([]byte("\n"))
	}
	cfgfile.Write(data)
	return nil
}