/ cmd / hometui / main.go
main.go
  1  package main
  2  
  3  import (
  4  	"bufio"
  5  	"encoding/json"
  6  	"flag"
  7  	"fmt"
  8  	"os"
  9  	"path/filepath"
 10  	"strings"
 11  
 12  	"github.com/artur9010/HomeTUI/internal/ha"
 13  	"github.com/artur9010/HomeTUI/internal/tui"
 14  )
 15  
 16  func getConfigPath() string {
 17  	homeDir, err := os.UserHomeDir()
 18  	if err != nil {
 19  		return "config.json"
 20  	}
 21  	return filepath.Join(homeDir, ".config", "hometui", "config.json")
 22  }
 23  
 24  func ensureConfigDir() error {
 25  	configPath := getConfigPath()
 26  	configDir := filepath.Dir(configPath)
 27  	return os.MkdirAll(configDir, 0755)
 28  }
 29  
 30  func promptForConfig() (*tui.Config, string, string) {
 31  	reader := bufio.NewReader(os.Stdin)
 32  
 33  	fmt.Println("No config file found. Please provide your Home Assistant details:")
 34  	fmt.Println()
 35  
 36  	fmt.Print("Home Assistant URL (e.g., http://homeassistant.local:8123): ")
 37  	url, _ := reader.ReadString('\n')
 38  	url = strings.TrimSpace(url)
 39  
 40  	fmt.Print("Long-lived access token: ")
 41  	token, _ := reader.ReadString('\n')
 42  	token = strings.TrimSpace(token)
 43  
 44  	fmt.Println()
 45  
 46  	cfg := &tui.Config{
 47  		HAURL:   url,
 48  		HAToken: token,
 49  	}
 50  
 51  	return cfg, url, token
 52  }
 53  
 54  func main() {
 55  	configPath := flag.String("config", getConfigPath(), "Path to configuration file")
 56  	flag.Parse()
 57  
 58  	var cfg *tui.Config
 59  	var url, token string
 60  
 61  	if _, err := os.Stat(*configPath); os.IsNotExist(err) {
 62  		cfg, url, token = promptForConfig()
 63  
 64  		fmt.Print("Save configuration to file? (y/n): ")
 65  		reader := bufio.NewReader(os.Stdin)
 66  		save, _ := reader.ReadString('\n')
 67  		save = strings.TrimSpace(strings.ToLower(save))
 68  
 69  		if save == "y" || save == "yes" {
 70  			if err := ensureConfigDir(); err != nil {
 71  				fmt.Printf("Warning: failed to create config directory: %v\n", err)
 72  			}
 73  
 74  			appConfig := struct {
 75  				HomeAssistant   struct {
 76  					URL   string `json:"url"`
 77  					Token string `json:"token"`
 78  				} `json:"homeassistant"`
 79  				ShowOnlyFavorites bool `json:"showOnlyFavorites"`
 80  			}{
 81  				HomeAssistant: struct {
 82  					URL   string `json:"url"`
 83  					Token string `json:"token"`
 84  				}{
 85  					URL:   url,
 86  					Token: token,
 87  				},
 88  				ShowOnlyFavorites: false,
 89  			}
 90  
 91  			data, err := json.MarshalIndent(appConfig, "", "  ")
 92  			if err != nil {
 93  				fmt.Printf("Warning: failed to marshal config: %v\n", err)
 94  			} else if err := os.WriteFile(*configPath, data, 0600); err != nil {
 95  				fmt.Printf("Warning: failed to save config file: %v\n", err)
 96  			} else {
 97  				fmt.Printf("Configuration saved to %s\n", *configPath)
 98  			}
 99  		}
100  		fmt.Println()
101  	} else {
102  		data, err := os.ReadFile(*configPath)
103  		if err != nil {
104  			fmt.Fprintf(os.Stderr, "Error loading config: %v\n", err)
105  			os.Exit(1)
106  		}
107  
108  		var appConfig struct {
109  			HomeAssistant   struct {
110  				URL   string `json:"url"`
111  				Token string `json:"token"`
112  			} `json:"homeassistant"`
113  			ShowOnlyFavorites bool `json:"showOnlyFavorites"`
114  		}
115  
116  		if err := json.Unmarshal(data, &appConfig); err != nil {
117  			fmt.Fprintf(os.Stderr, "Error parsing config: %v\n", err)
118  			os.Exit(1)
119  		}
120  
121  		url = appConfig.HomeAssistant.URL
122  		token = appConfig.HomeAssistant.Token
123  
124  		if url == "" || token == "" {
125  			fmt.Println("Config file exists but credentials are missing or invalid.")
126  			fmt.Println("Please re-enter your Home Assistant details:")
127  			fmt.Println()
128  
129  			cfg, url, token = promptForConfig()
130  
131  			fmt.Print("Save configuration to file? (y/n): ")
132  			reader := bufio.NewReader(os.Stdin)
133  			save, _ := reader.ReadString('\n')
134  			save = strings.TrimSpace(strings.ToLower(save))
135  
136  			if save == "y" || save == "yes" {
137  				if err := ensureConfigDir(); err != nil {
138  					fmt.Printf("Warning: failed to create config directory: %v\n", err)
139  				}
140  
141  				appConfig.HomeAssistant.URL = url
142  				appConfig.HomeAssistant.Token = token
143  
144  				data, err := json.MarshalIndent(appConfig, "", "  ")
145  				if err != nil {
146  					fmt.Printf("Warning: failed to marshal config: %v\n", err)
147  				} else if err := os.WriteFile(*configPath, data, 0600); err != nil {
148  					fmt.Printf("Warning: failed to save config file: %v\n", err)
149  				} else {
150  					fmt.Printf("Configuration saved to %s\n", *configPath)
151  				}
152  			}
153  			fmt.Println()
154  		}
155  
156  		cfg = &tui.Config{
157  			HAURL:   url,
158  			HAToken: token,
159  		}
160  	}
161  
162  	if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
163  		url = "http://" + url
164  	}
165  
166  	wsURL := strings.Replace(url, "http", "ws", 1)
167  	if !strings.HasSuffix(wsURL, "/api/websocket") {
168  		wsURL = wsURL + "/api/websocket"
169  	}
170  
171  	haClient := ha.NewClient(url, token)
172  	wsClient := ha.NewWSClient(wsURL, token)
173  
174  	if err := tui.Start(cfg, haClient, wsClient); err != nil {
175  		fmt.Fprintf(os.Stderr, "Error running TUI: %v\n", err)
176  		os.Exit(1)
177  	}
178  }