//go:build darwin package main import ( "bytes" "fmt" "log" "net/http" "os" "os/exec" "os/signal" "syscall" "time" "github.com/crgimenes/glaze" "vpnclient/internal/apphost" "vpnclient/internal/config" "vpnclient/internal/core" "vpnclient/internal/update" ) func main() { if update.MaybeFinishUpdate(os.Args[1:]) { return } update.CleanupStaleDownloads() log.SetFlags(log.LstdFlags | log.Lshortfile) cfgPath, err := config.LocateConfig() if err != nil { fatalf("Не удалось найти путь конфига: %v", err) } if _, err := os.Stat(cfgPath); os.IsNotExist(err) { if err := config.WriteExample(cfgPath); err != nil { fatalf("Не удалось создать конфиг: %v", err) } } cfg, err := config.Load(cfgPath) if err != nil { fatalf("Ошибка конфига %s: %v", cfgPath, err) } logBuf := &bytes.Buffer{} mgr, err := core.NewManager(cfgPath, cfg, logBuf) if err != nil { fatalf("%v", err) } a := apphost.New(mgr, cfgPath, logBuf) a.OpenURL = func(u string) error { return exec.Command("open", u).Start() } a.OnAfterUpdate = func() { go func() { time.Sleep(300 * time.Millisecond) os.Exit(0) }() } ln, uiURL, token, err := apphost.ListenLocal() if err != nil { fatalf("listen: %v", err) } a.APIToken = token srv := &http.Server{Handler: a.Handler()} go func() { _ = srv.Serve(ln) }() go a.AutoCheckUpdate() w, err := glaze.New(false) if err != nil || w == nil { log.Printf("webview unavailable (%v); opening default browser", err) if err2 := exec.Command("open", uiURL).Run(); err2 != nil { fatalf("Не удалось открыть интерфейс:\n%v\n%v\n%s", err, err2, uiURL) } log.Printf("Navis UI: %s", uiURL) sig := make(chan os.Signal, 1) signal.Notify(sig, os.Interrupt, syscall.SIGTERM) <-sig _ = mgr.Disconnect() _ = srv.Close() return } defer func() { _ = mgr.Disconnect() _ = srv.Close() w.Destroy() }() w.SetTitle("Navis 2") w.SetSize(500, 900, glaze.HintNone) w.Navigate(uiURL) log.Printf("Navis UI: %s", uiURL) w.Run() } func fatalf(format string, args ...any) { msg := fmt.Sprintf(format, args...) log.Println(msg) _ = exec.Command("osascript", "-e", fmt.Sprintf(`display alert "Navis" message %q`, msg)).Run() os.Exit(1) }