1package usecase
2
3import (
4 "context"
5
6 "github.com/bnema/dumber/internal/application/port"
7 "github.com/bnema/dumber/internal/logging"
8)
9
10// InstallDesktopInput contains the input for the install operation.
11type InstallDesktopInput struct {
12 IconData []byte
13}
14
15// InstallDesktopUseCase installs the desktop file for system integration.
16type InstallDesktopUseCase struct {
17 desktop port.DesktopIntegration
18}
19
20// NewInstallDesktopUseCase creates a new InstallDesktopUseCase.
21func NewInstallDesktopUseCase(desktop port.DesktopIntegration) *InstallDesktopUseCase {
22 return &InstallDesktopUseCase{desktop: desktop}
23}
24
25// InstallDesktopOutput contains the result of the install operation.
26type InstallDesktopOutput struct {
27 DesktopPath string
28 IconPath string
29 WasDesktopExisting bool
30 WasIconExisting bool
31}
32
33// Execute installs the desktop file and icon.
34func (uc *InstallDesktopUseCase) Execute(ctx context.Context, input InstallDesktopInput) (*InstallDesktopOutput, error) {
35 log := logging.FromContext(ctx)
36
37 // Check current status first
38 status, err := uc.desktop.GetStatus(ctx)
39 if err != nil {
40 return nil, err
41 }
42
43 output := &InstallDesktopOutput{
44 WasDesktopExisting: status.DesktopFileInstalled,
45 WasIconExisting: status.IconInstalled,
46 }
47
48 // Install desktop file
49 desktopPath, err := uc.desktop.InstallDesktopFile(ctx)
50 if err != nil {
51 return nil, err
52 }
53 output.DesktopPath = desktopPath
54
55 // Install icon if data provided
56 if len(input.IconData) > 0 {
57 iconPath, err := uc.desktop.InstallIcon(ctx, input.IconData)
58 if err != nil {
59 return nil, err
60 }
61 output.IconPath = iconPath
62 }
63
64 log.Info().
65 Str("desktop_path", output.DesktopPath).
66 Str("icon_path", output.IconPath).
67 Bool("was_desktop_existing", output.WasDesktopExisting).
68 Bool("was_icon_existing", output.WasIconExisting).
69 Msg("desktop install complete")
70
71 return output, nil
72}
73
74// SetDefaultBrowserUseCase sets dumber as the default web browser.
75type SetDefaultBrowserUseCase struct {
76 desktop port.DesktopIntegration
77}
78
79// NewSetDefaultBrowserUseCase creates a new SetDefaultBrowserUseCase.
80func NewSetDefaultBrowserUseCase(desktop port.DesktopIntegration) *SetDefaultBrowserUseCase {
81 return &SetDefaultBrowserUseCase{desktop: desktop}
82}
83
84// SetDefaultOutput contains the result of the set-default operation.
85type SetDefaultOutput struct {
86 WasAlreadyDefault bool
87}
88
89// Execute sets dumber as the default browser.
90func (uc *SetDefaultBrowserUseCase) Execute(ctx context.Context) (*SetDefaultOutput, error) {
91 log := logging.FromContext(ctx)
92
93 // Check current status
94 status, err := uc.desktop.GetStatus(ctx)
95 if err != nil {
96 return nil, err
97 }
98
99 if status.IsDefaultBrowser {
100 log.Debug().Msg("dumber is already default browser")
101 return &SetDefaultOutput{WasAlreadyDefault: true}, nil
102 }
103
104 // Set as default
105 if err := uc.desktop.SetAsDefaultBrowser(ctx); err != nil {
106 return nil, err
107 }
108
109 return &SetDefaultOutput{WasAlreadyDefault: false}, nil
110}
111
112// RemoveDesktopUseCase removes desktop integration files.
113type RemoveDesktopUseCase struct {
114 desktop port.DesktopIntegration
115}
116
117// NewRemoveDesktopUseCase creates a new RemoveDesktopUseCase.
118func NewRemoveDesktopUseCase(desktop port.DesktopIntegration) *RemoveDesktopUseCase {
119 return &RemoveDesktopUseCase{desktop: desktop}
120}
121
122// RemoveDesktopOutput contains the result of the remove operation.
123type RemoveDesktopOutput struct {
124 WasDesktopInstalled bool
125 WasIconInstalled bool
126 WasDefault bool
127 RemovedDesktopPath string
128 RemovedIconPath string
129}
130
131// Execute removes desktop integration.
132func (uc *RemoveDesktopUseCase) Execute(ctx context.Context) (*RemoveDesktopOutput, error) {
133 log := logging.FromContext(ctx)
134
135 // Check current status
136 status, err := uc.desktop.GetStatus(ctx)
137 if err != nil {
138 return nil, err
139 }
140
141 output := &RemoveDesktopOutput{
142 WasDesktopInstalled: status.DesktopFileInstalled,
143 WasIconInstalled: status.IconInstalled,
144 WasDefault: status.IsDefaultBrowser,
145 RemovedDesktopPath: status.DesktopFilePath,
146 RemovedIconPath: status.IconFilePath,
147 }
148
149 // Unset as default browser first (if applicable)
150 if status.IsDefaultBrowser {
151 if err := uc.desktop.UnsetAsDefaultBrowser(ctx); err != nil {
152 log.Warn().Err(err).Msg("failed to unset default browser")
153 }
154 }
155
156 // Remove desktop file
157 if err := uc.desktop.RemoveDesktopFile(ctx); err != nil {
158 return nil, err
159 }
160
161 // Remove icon file
162 if err := uc.desktop.RemoveIcon(ctx); err != nil {
163 return nil, err
164 }
165
166 log.Info().
167 Bool("was_desktop_installed", output.WasDesktopInstalled).
168 Bool("was_icon_installed", output.WasIconInstalled).
169 Bool("was_default", output.WasDefault).
170 Msg("desktop integration removed")
171
172 return output, nil
173}