<commit_before>package main

import (
	"bufio"
	"fmt"
	"os"
	"regexp"
	"strings"

	"github.com/BurntSushi/toml"
	"github.com/skratchdot/open-golang/open"
)

const AuthURL = "http://slackcat.chat/configure"

// Slack team and channel read from file
type Config struct {
	Teams          map[string]string `toml:"teams"`
	DefaultTeam    string            `toml:"default_team"`
	DefaultChannel string            `toml:"default_channel"`
}

// Return new default config
func NewConfig() *Config {
	return &Config{
		Teams: make(map[string]string),
	}
}

// Return config read from file
func ReadConfig(path string) *Config {
	config := NewConfig()
	lines, err := readLines(path)
	failOnError(err, "unable to read config")

	// simple config file
	if len(lines) == 1 {
		config.Teams["default"] = lines[0]
		config.DefaultTeam = "default"
		return config
	}

	// advanced config file
	body := strings.Join(lines, "\n")
	_, err = toml.Decode(body, &config)
	failOnError(err, "failed to parse config")

	return config
}

func (c *Config) Write(path string) {
	cfgdir := basedir(path)
	// create config dir if not exist
	if _, err := os.Stat(cfgdir); err != nil {
		err = os.Mkdir(cfgdir, 0755)
		if err != nil {
			exitErr(fmt.Errorf("failed to initialize config dir: %s", err))
		}
	}

	file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0644)
	if err != nil {
		exitErr(fmt.Errorf("failed to open config for writing: %s", err))
	}

	writer := toml.NewEncoder(file)
	err = writer.Encode(c)
	if err != nil {
		exitErr(fmt.Errorf("failed to write config: %s", err))
	}
}

func (c *Config) parseChannelOpt(channel string) (string, string, error) {
	// use default channel if none provided
	if channel == "" {
		if c.DefaultChannel == "" {
			return "", "", fmt.Errorf("no channel provided")
		}
		return c.DefaultTeam, c.DefaultChannel, nil
	}
	// if channel is prefixed with a team
	if strings.Contains(channel, ":") {
		s := strings.Split(channel, ":")
		return s[0], s[1], nil
	}
	// use default team with provided channel
	return c.DefaultTeam, channel, nil
}

// determine config path from environment
func getConfigPath() (path string, exists bool) {
	userHome, ok := os.LookupEnv("HOME")
	if !ok {
		exitErr(fmt.Errorf("$HOME not set"))
	}

	if xdgSupport() {
		xdgHome, ok := os.LookupEnv("XDG_CONFIG_HOME")
		if !ok {
			xdgHome = fmt.Sprintf("%s/.config", userHome)
		}
		path = fmt.Sprintf("%s/slackcat/config", xdgHome)
	} else {
		fmt.Sprintf("%s/.slackcat", userHome)
	}

	if _, err := os.Stat(path); err == nil {
		exists = true
	}

	return path, exists
}

func basedir(path string) string {
	parts := strings.Split(path, "/")
	return strings.Join((parts[0 : len(parts)-1]), "/")
}

// Test for environemnt supporting XDG spec
func xdgSupport() bool {<commit_msg>set path to Sprintf return value<commit_after>package main

import (
	"bufio"
	"fmt"
	"os"
	"regexp"
	"strings"

	"github.com/BurntSushi/toml"
	"github.com/skratchdot/open-golang/open"
)

const AuthURL = "http://slackcat.chat/configure"

// Slack team and channel read from file
type Config struct {
	Teams          map[string]string `toml:"teams"`
	DefaultTeam    string            `toml:"default_team"`
	DefaultChannel string            `toml:"default_channel"`
}

// Return new default config
func NewConfig() *Config {
	return &Config{
		Teams: make(map[string]string),
	}
}

// Return config read from file
func ReadConfig(path string) *Config {
	config := NewConfig()
	lines, err := readLines(path)
	failOnError(err, "unable to read config")

	// simple config file
	if len(lines) == 1 {
		config.Teams["default"] = lines[0]
		config.DefaultTeam = "default"
		return config
	}

	// advanced config file
	body := strings.Join(lines, "\n")
	_, err = toml.Decode(body, &config)
	failOnError(err, "failed to parse config")

	return config
}

func (c *Config) Write(path string) {
	cfgdir := basedir(path)
	// create config dir if not exist
	if _, err := os.Stat(cfgdir); err != nil {
		err = os.Mkdir(cfgdir, 0755)
		if err != nil {
			exitErr(fmt.Errorf("failed to initialize config dir [%s]: %s", cfgdir, err))
		}
	}

	file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0644)
	if err != nil {
		exitErr(fmt.Errorf("failed to open config for writing: %s", err))
	}

	writer := toml.NewEncoder(file)
	err = writer.Encode(c)
	if err != nil {
		exitErr(fmt.Errorf("failed to write config: %s", err))
	}
}

func (c *Config) parseChannelOpt(channel string) (string, string, error) {
	// use default channel if none provided
	if channel == "" {
		if c.DefaultChannel == "" {
			return "", "", fmt.Errorf("no channel provided")
		}
		return c.DefaultTeam, c.DefaultChannel, nil
	}
	// if channel is prefixed with a team
	if strings.Contains(channel, ":") {
		s := strings.Split(channel, ":")
		return s[0], s[1], nil
	}
	// use default team with provided channel
	return c.DefaultTeam, channel, nil
}

// determine config path from environment
func getConfigPath() (path string, exists bool) {
	userHome, ok := os.LookupEnv("HOME")
	if !ok {
		exitErr(fmt.Errorf("$HOME not set"))
	}

	if xdgSupport() {
		xdgHome, ok := os.LookupEnv("XDG_CONFIG_HOME")
		if !ok {
			xdgHome = fmt.Sprintf("%s/.config", userHome)
		}
		path = fmt.Sprintf("%s/slackcat/config", xdgHome)
	} else {
		path = fmt.Sprintf("%s/.slackcat", userHome)
	}

	if _, err := os.Stat(path); err == nil {
		exists = true
	}

	return path, exists
}

func basedir(path string) string {
	parts := strings.Split(path, "/")
	return strings.Join((parts[0 : len(parts)-1]), "/")
}

// Test for environemnt supporting XDG spec
func xdgSupport() bool {
{'fraction_non_alphanumeric': 0.1510481992474467, 'fraction_numerical': 0.0050170220390611, 'mean_word_length': 3.6907563025210086, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1236102', 'n_tokens_mistral': 2053, 'n_tokens_neox': 1950, 'n_words': 536}