services.go

 1package app
 2
 3import (
 4	"context"
 5	"database/sql"
 6
 7	"github.com/kujtimiihoxha/termai/internal/config"
 8	"github.com/kujtimiihoxha/termai/internal/db"
 9	"github.com/kujtimiihoxha/termai/internal/logging"
10	"github.com/kujtimiihoxha/termai/internal/lsp"
11	"github.com/kujtimiihoxha/termai/internal/lsp/watcher"
12	"github.com/kujtimiihoxha/termai/internal/message"
13	"github.com/kujtimiihoxha/termai/internal/permission"
14	"github.com/kujtimiihoxha/termai/internal/pubsub"
15	"github.com/kujtimiihoxha/termai/internal/session"
16	"github.com/kujtimiihoxha/termai/internal/tui/util"
17)
18
19type App struct {
20	Context context.Context
21
22	Sessions    session.Service
23	Messages    message.Service
24	Permissions permission.Service
25
26	LSPClients map[string]*lsp.Client
27
28	Logger logging.Interface
29
30	Status  *pubsub.Broker[util.InfoMsg]
31	ceanups []func()
32}
33
34func New(ctx context.Context, conn *sql.DB) *App {
35	cfg := config.Get()
36	q := db.New(conn)
37	log := logging.NewLogger(logging.Options{
38		Level: cfg.Log.Level,
39	})
40	sessions := session.NewService(ctx, q)
41	messages := message.NewService(ctx, q)
42
43	app := &App{
44		Context:     ctx,
45		Sessions:    sessions,
46		Messages:    messages,
47		Permissions: permission.NewPermissionService(),
48		Logger:      log,
49		Status:      pubsub.NewBroker[util.InfoMsg](),
50		LSPClients:  make(map[string]*lsp.Client),
51	}
52
53	for name, client := range cfg.LSP {
54		lspClient, err := lsp.NewClient(client.Command, client.Args...)
55		app.ceanups = append(app.ceanups, func() {
56			lspClient.Close()
57		})
58		workspaceWatcher := watcher.NewWorkspaceWatcher(lspClient)
59		if err != nil {
60			log.Error("Failed to create LSP client for", name, err)
61			continue
62		}
63
64		_, err = lspClient.InitializeLSPClient(ctx, config.WorkingDirectory())
65		if err != nil {
66			log.Error("Initialize failed", "error", err)
67			continue
68		}
69		go workspaceWatcher.WatchWorkspace(ctx, config.WorkingDirectory())
70		app.LSPClients[name] = lspClient
71	}
72	return app
73}
74
75func (a *App) Close() {
76	for _, cleanup := range a.ceanups {
77		cleanup()
78	}
79	for _, client := range a.LSPClients {
80		client.Close()
81	}
82	a.Logger.Info("App closed")
83}