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, u 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(u)
		if !changed {
			lastMatch = i
		}
		// Use a relative URL to work in presence of stripping/redirects in webui.go.
		rel := &url.URL{RawQuery: dst.RawQuery, ForceQuery: true}
		result[i] = configMenuEntry{
			Name:       cfg.Name,
			URL:        rel.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)
	})
}
