package driver

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/url"
	"os"
	"path/filepath"
)

// settings holds pprof settings.
type settings struct {
	// Configs holds a list of named UI configurations.
	Configs []namedConfig `json:"configs"`
}

// namedConfig associates a name with a config.
type namedConfig struct {
	Name string `json:"name"`
	config
}

// settingsFileName returns the name of the file where settings should be saved.
func settingsFileName() (string, error) {
	// Return "pprof/settings.json" under os.UserConfigDir().
	dir, err := os.UserConfigDir()
	if err != nil {
		return "", err
	}
	return filepath.Join(dir, "pprof", "settings.json"), nil
}

// readSettings reads settings from fname.
func readSettings(fname string) (*settings, error) {
	data, err := ioutil.ReadFile(fname)
	if err != nil {
		if os.IsNotExist(err) {
			return &settings{}, nil
		}
		return nil, fmt.Errorf("could not read settings: %w", err)
	}
	settings := &settings{}
	if err := json.Unmarshal(data, settings); err != nil {
		return nil, fmt.Errorf("could not parse settings: %w", err)
	}
	for i := range settings.Configs {
		settings.Configs[i].resetTransient()
	}
	return settings, nil
}

// writeSettings saves settings to fname.
func writeSettings(fname string, settings *settings) error {
	data, err := json.MarshalIndent(settings, "", "  ")
	if err != nil {
		return fmt.Errorf("could not encode settings: %w", err)
	}

	// create the settings directory if it does not exist
	// XDG specifies permissions 0700 when creating settings dirs:
	// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
	if err := os.MkdirAll(filepath.Dir(fname), 0700); err != nil {
		return fmt.Errorf("failed to create settings directory: %w", err)
	}

	if err := ioutil.WriteFile(fname, data, 0644); err != nil {
		return fmt.Errorf("failed to write settings: %w", err)
	}
	return nil
}

// configMenuEntry holds information for a single config menu entry.
type configMenuEntry struct {
	Name       string
	URL        string
	Current    bool // Is this the currently selected config?
	UserConfig bool // Is this a user-provided config?
}

// configMenu returns a list of items to add to a menu in the web UI.
func configMenu(fname string, url url.URL) []configMenuEntry {
	// Start with system configs.
	configs := []namedConfig{{Name: "Default", config: defaultConfig()}}
	if settings, err := readSettings(fname); err == nil {
		// Add user configs.
		configs = append(configs, settings.Configs...)
	}

	// Convert to menu entries.
	result := make([]configMenuEntry, len(configs))
	lastMatch := -1
	for i, cfg := range configs {
		dst, changed := cfg.config.makeURL(url)
		if !changed {
			lastMatch = i
		}
		result[i] = configMenuEntry{
			Name:       cfg.Name,
			URL:        dst.String(),
			UserConfig: (i != 0),
		}
	}
	// Mark the last matching config as currennt
	if lastMatch >= 0 {
		result[lastMatch].Current = true
	}
	return result
}

// editSettings edits settings by applying fn to them.
func editSettings(fname string, fn func(s *settings) error) error {
	settings, err := readSettings(fname)
	if err != nil {
		return err
	}
	if err := fn(settings); err != nil {
		return err
	}
	return writeSettings(fname, settings)
}

// setConfig saves the config specified in request to fname.
func setConfig(fname string, request url.URL) error {
	q := request.Query()
	name := q.Get("config")
	if name == "" {
		return fmt.Errorf("invalid config name")
	}
	cfg := currentConfig()
	if err := cfg.applyURL(q); err != nil {
		return err
	}
	return editSettings(fname, func(s *settings) error {
		for i, c := range s.Configs {
			if c.Name == name {
				s.Configs[i].config = cfg
				return nil
			}
		}
		s.Configs = append(s.Configs, namedConfig{Name: name, config: cfg})
		return nil
	})
}

// removeConfig removes config from fname.
func removeConfig(fname, config string) error {
	return editSettings(fname, func(s *settings) error {
		for i, c := range s.Configs {
			if c.Name == config {
				s.Configs = append(s.Configs[:i], s.Configs[i+1:]...)
				return nil
			}
		}
		return fmt.Errorf("config %s not found", config)
	})
}
