package session import ( "fmt" "sync" "github.com/google/uuid" ) const MaxSessions = 32 type Manager struct { mu sync.RWMutex sessions map[string]*SessionInfo } func NewManager() *Manager { return &Manager{ sessions: make(map[string]*SessionInfo), } } func (m *Manager) Create(connectionID int64, protocol string) (*SessionInfo, error) { m.mu.Lock() defer m.mu.Unlock() if len(m.sessions) >= MaxSessions { return nil, fmt.Errorf("maximum sessions (%d) reached", MaxSessions) } s := &SessionInfo{ ID: uuid.NewString(), ConnectionID: connectionID, Protocol: protocol, State: StateConnecting, TabPosition: len(m.sessions), } m.sessions[s.ID] = s return s, nil } func (m *Manager) Get(id string) (*SessionInfo, bool) { m.mu.RLock() defer m.mu.RUnlock() s, ok := m.sessions[id] return s, ok } func (m *Manager) List() []*SessionInfo { m.mu.RLock() defer m.mu.RUnlock() list := make([]*SessionInfo, 0, len(m.sessions)) for _, s := range m.sessions { list = append(list, s) } return list } func (m *Manager) SetState(id string, state SessionState) error { m.mu.Lock() defer m.mu.Unlock() s, ok := m.sessions[id] if !ok { return fmt.Errorf("session %s not found", id) } s.State = state return nil } func (m *Manager) Detach(id string) error { return m.SetState(id, StateDetached) } func (m *Manager) Reattach(id, windowID string) error { m.mu.Lock() defer m.mu.Unlock() s, ok := m.sessions[id] if !ok { return fmt.Errorf("session %s not found", id) } s.State = StateConnected s.WindowID = windowID return nil } func (m *Manager) Remove(id string) { m.mu.Lock() defer m.mu.Unlock() delete(m.sessions, id) } func (m *Manager) Count() int { m.mu.RLock() defer m.mu.RUnlock() return len(m.sessions) }