package config

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

	"github.com/deranjer/store"
)

// ConfigPath is the global path to the config that is injected from the main server package.
//var ConfigPath string

// DefaultConfigPath contains the default location for the serverConfig.toml
var DefaultConfigPath = "config" + string(os.PathSeparator) + "serverConfig.toml"

// FindConfig Search for the config it 2 places, root and in the config/ folder
func FindConfig() (string, error) {
	configRootLoc, err := os.Stat("serverConfig.toml") //First checking root directory
	if err != nil {
		configFile, err := os.Stat(DefaultConfigPath) // If not in root dir, check default dir
		if err != nil {
			return "", err
		}
		if !configFile.IsDir() {
			return DefaultConfigPath, nil
		}
		return "", fmt.Errorf("config not found: %s", err)
	}
	if !configRootLoc.IsDir() { // Make sure the .toml file isn't a directory
		return "serverConfig.toml", nil //setting the config path to root
	}
	return "", fmt.Errorf("serverConfig.toml does not appear to be in the correct file format")
}

// ValidateConfig will go through the entire config and do basic sanity checks and write valid values to the server struct if some are missing
func ValidateConfig(conf *GvcServerConfig, configPath string, version string) error {
	if conf.Version == "" { // No version found, should we update it?
		fmt.Printf("No version found, inputing current server version: %s\n", version)
		conf.Version = version
	}
	if conf.LogFile == "" { // If no log file specified, set log location
		fmt.Printf("No logfile found in config, setting it to: gvclog.log :in root dir:")
		conf.LogFile = "gvclog.log"
	}
	if conf.RepoRootPath == "" {
		fmt.Println("Repo root path: ", conf.RepoRootPath)
		path, err := os.Getwd()
		if err != nil {
			return fmt.Errorf("unable to get current working directory, and rootpath for the repos is not set: %s", err)
		}
		path = path + string(os.PathSeparator) + "repos"
		err = os.Mkdir(path, 0644)
		if err != nil {
			return fmt.Errorf("unable to create 'repos' dir in current working dir: %s", err)
		}
		fmt.Printf("No repo root path found, inputting current working directory + repos: %s\n", path)
		conf.RepoRootPath = path //Writing path back to config struct
	} else {
		repoFolder, err := os.Stat(conf.RepoRootPath)
		if err != nil { //If folder is not found, try to create
			if !filepath.IsAbs(conf.RepoRootPath) {
				fmt.Println("repo folder does not appear to be absolute path, using relative to create direcotry...", conf.RepoRootPath)
			} else {
				fmt.Println("repo folder appears to be absolute path, creating dir: ", conf.RepoRootPath)
			}
			err = os.MkdirAll(conf.RepoRootPath, 0644)
			if err != nil {
				return fmt.Errorf("unable to make repo directory: %s", err)
			}
		} else { // If path exists, ensure it is directory
			if !repoFolder.IsDir() { //If path leads to a file, not folder, return err
				return fmt.Errorf("provided repo path leads to a file, not folder, cannot continue, please fix path")
			}
		}
	}
	// Range through the repos and run some basic validation on all of them
	// for i, repo := range conf.Repos {
	// 	err := validateCompress(repo)
	// 	if err != nil {
	// 		return err
	// 	}
	// 	//TODO validate ignores (pretty similar to compress)
	// }
	// Done making changes, so if any changes, write it to the toml file
	err := store.Save(configPath, &conf) // Save our new config back to TOML so it can be read in
	if err != nil {
		log.Fatalf("unable to save config to toml file after validation: %s", err)
	}
	return nil
}

// validateCompress checks the compression settings to make sure they are valid //TODO return error needed?
// func validateCompress(repo RepoConfig) error {
// 	compress := repo.NoCompress
// 	for i, file := range compress.Files {
// 		if file == "" {
// 			fmt.Println("empty file in compress files, removing... ")
// 			compress.Files[i] = compress.Files[len(compress.Files)-1]
// 			continue
// 		}
// 		// TODO: write more validation
// 	}
// 	for i, folder := range compress.Folders {
// 		file, err := os.Stat(folder) // TODO: check to see if it returns ABS or not, might need to convert
// 		if err != nil {
// 			continue
// 		}
// 		fileType := file.Mode()
// 		if fileType.IsRegular() { // Not a folder
// 			fmt.Println("compressed folder in array is not actually a folder, moving it to file compress: ", folder)
// 			compress.Folders[i] = compress.Folders[len(compress.Folders)-1]
// 			compress.Files = append(compress.Files, folder)
// 			continue
// 		}
// 	}
// 	for i, ext := range compress.Exts {
// 		if ext == "" {
// 			fmt.Println("empty ext in compress exts, removing... ")
// 			compress.Exts[i] = compress.Exts[len(compress.Exts)-1]
// 			continue
// 		}
// 		// TODO: validate there is a "." in front of the ext, if not add it?
// 	}
// 	err := store.Save(ConfigPath, &conf)
// 	if err != nil {
// 		fmt.Println("Error saving config back to toml file: ", err)
// 	}
// 	return nil
// }
