package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"text/tabwriter"
	"unicode"
)

type App struct {
	Name      string            `json:"name"`
	Shortcuts map[string]string `json:"shortcuts"`
}

type Config struct {
	Apps []App `json:"apps"`
}

func loadConfig(dir string) Config {
	apps := []App{}

	// Ouvre le répertoire config
	files, err := ioutil.ReadDir(dir)
	if err != nil {
		//panic(err)
		fmt.Println("Le répertoire config est inexistant !")
		os.Exit(1)
	}

	// Lis tous les fichiers .json
	for _, file := range files {
		if filepath.Ext(file.Name()) == ".json" {
			data, _ := ioutil.ReadFile(dir + "/" + file.Name())
			var app App
			json.Unmarshal(data, &app)
			apps = append(apps, app)
		}
	}
	config := Config{
		Apps: apps,
	}
	return config
}

func main() {

	underline := "- -- - -- - -- - -- - -- - -- - -- - -- - -- - --"

	flag.Usage = func() {
		fmt.Println("")
		fmt.Println(underline)
		fmt.Println("  Scut-Reminder : Gestion des raccourcis")
		fmt.Println(underline)
		fmt.Println("\n     Options :")
		fmt.Println(underline)
		fmt.Printf(" -c PathDuDossierConfig     	|| Path du dossier de configuration au lieu du répertoire ./config (par défaut)\n")
		fmt.Printf(" -a Nom Application        	|| Afficher les raccourcis de l'application spécifiée\n")
		fmt.Printf(" -f fitre        		|| Filtrer les raccourcis qui contiennent le filtre\n")
		fmt.Printf(" -h                        	|| Afficher cette aide\n")
		fmt.Println("")
		fmt.Println("     Example :")
		fmt.Println(underline)
		fmt.Printf(" scut				  || Affiche la liste des applications\n\n")
		fmt.Printf(" scut -c MaConfig.json -a \"nevim\" || Affiche liste des raccourcis de nevim de MaConfig.json \n\n")
		fmt.Printf(" scut -a \"Visual Studio Code\" 	  || Affiche liste des raccourcis de vscode \n\n")
		fmt.Printf(" scut -a \"Kitty\" -f quit 	  || Affiche liste des raccourcis qui contient 'quit' \n\n")
		fmt.Println("")
	}

	configDir := flag.String("c", "~/.config/scut/config/", "Config directory")

	appName := flag.String("a", "", "Application name")

	filter := flag.String("f", "", "Filter")
	flag.Parse()

	config := loadConfig(*configDir)

	cleanFilter := strings.TrimFunc(*filter, func(r rune) bool {
		return !unicode.IsGraphic(r)
	})

	if *appName == "" {
		// List all applications
		fmt.Println(underline)
		fmt.Println("          A P P L I C A T I O N S")
		fmt.Println(underline)
		for _, app := range config.Apps {
			fmt.Printf("%s\n", app.Name)
		}
		fmt.Println()
	} else {
		w := tabwriter.NewWriter(os.Stdout, 0, 0, 10, '.', 0)
		if *filter != "" {
			for _, app := range config.Apps {
				if strings.ToUpper(app.Name) == strings.ToUpper(*appName) {
					fmt.Println(underline)
					fmt.Fprintln(w, "          S H O R T C U T S : "+app.Name)
					fmt.Println(underline)
					for shortcut, desc := range app.Shortcuts {
						if strings.Contains(strings.ToUpper(shortcut), strings.ToUpper(cleanFilter)) || strings.Contains(strings.ToUpper(desc), strings.ToUpper(cleanFilter)) {
							fmt.Fprintf(w, "%s \t %s\n", shortcut, desc)
						}
					}
				}
			}
			w.Flush()
		} else {
			for _, app := range config.Apps {
				if strings.ToUpper(app.Name) == strings.ToUpper(*appName) {
					fmt.Println(underline)
					fmt.Fprintln(w, "          S H O R T C U T S : "+app.Name)
					fmt.Println(underline)
					for shortcut, desc := range app.Shortcuts {
						fmt.Fprintf(w, "%s \t %s\n", shortcut, desc)
					}
				}
			}
			w.Flush()
		}
	}

}
