1package remote
2
3import (
4 "context"
5 "fmt"
6 "log/slog"
7
8 "github.com/bnema/vev/internal/adapters/dgram"
9 "github.com/bnema/vev/internal/adapters/sshstdio"
10 "github.com/bnema/vev/internal/ports"
11)
12
13// DialerFactory selects the requested remote transport adapter.
14type DialerFactory struct {
15 observer ports.SerializedRuntimeObserver
16}
17
18var _ ports.RemoteDialerFactory = DialerFactory{}
19
20func NewDialerFactory() DialerFactory { return DialerFactory{} }
21
22// NewDialerFactoryWithRuntimeObserver wires the one process-local sink into
23// whichever concrete remote carriage adapter is selected.
24func NewDialerFactoryWithRuntimeObserver(observer ports.SerializedRuntimeObserver) DialerFactory {
25 return DialerFactory{observer: observer}
26}
27
28func (f DialerFactory) DialerForRemote(target string, session string, mode ports.RemoteTransportMode, log *slog.Logger) (ports.Dialer, error) {
29 switch mode {
30 case ports.RemoteTransportUDP:
31 if log != nil {
32 log.Info("remote transport selected", "mode", mode, "target", target, "session", session)
33 }
34 dialer := dgram.NewRemoteDialerWithLogger(target, session, log)
35 dialer.RuntimeObserver = f.observer
36 return dialer, nil
37 case ports.RemoteTransportStdio:
38 if log != nil {
39 log.Info("remote transport selected", "mode", mode, "target", target, "session", session)
40 }
41 return stdioDialer{target: target, session: session, log: log, observer: f.observer}, nil
42 default:
43 return nil, fmt.Errorf("vev: unsupported remote transport %q", mode)
44 }
45}
46
47type stdioDialer struct {
48 target string
49 session string
50 log *slog.Logger
51 observer ports.SerializedRuntimeObserver
52}
53
54func (d stdioDialer) Dial(ctx context.Context) (ports.Transport, error) {
55 return sshstdio.DialContextWithRuntimeObserver(ctx, d.target, d.session, d.log, sshstdio.WithRuntimeObserver(d.observer))
56}