/**
 * test/tmux.test.ts (H1) — thin tmux CLI wrappers.
 *
 * execFileSync is mocked so no real tmux binary runs: every wrapper is
 * best-effort and must NOT throw (a throwing exec → false / no-op).
 */

import { describe, it, expect, vi, beforeEach } from 'vitest'

const mockExec = vi.fn()
vi.mock('node:child_process', () => ({
  execFileSync: (...a: unknown[]) => mockExec(...a),
}))

const { tmuxAvailable, tmuxName, hasSession, killSession } = await import('../src/session/tmux.js')

beforeEach(() => {
  mockExec.mockReset()
})

describe('tmuxName', () => {
  it('prefixes the session id with web_', () => {
    expect(tmuxName('abc')).toBe('web_abc')
  })
})

describe('tmuxAvailable', () => {
  it('returns true when `tmux -V` succeeds', () => {
    mockExec.mockReturnValue(Buffer.from('tmux 3.4'))
    expect(tmuxAvailable()).toBe(true)
    expect(mockExec).toHaveBeenCalledWith('tmux', ['-V'], { stdio: 'ignore' })
  })

  it('returns false when tmux is missing (exec throws)', () => {
    mockExec.mockImplementation(() => {
      throw new Error('ENOENT')
    })
    expect(tmuxAvailable()).toBe(false)
  })
})

describe('hasSession', () => {
  it('returns true when has-session exits 0', () => {
    mockExec.mockReturnValue(Buffer.from(''))
    expect(hasSession('web_x')).toBe(true)
    expect(mockExec).toHaveBeenCalledWith('tmux', ['has-session', '-t', 'web_x'], { stdio: 'ignore' })
  })

  it('returns false when has-session throws (no such session)', () => {
    mockExec.mockImplementation(() => {
      throw new Error("can't find session")
    })
    expect(hasSession('web_gone')).toBe(false)
  })
})

describe('killSession', () => {
  it('invokes tmux kill-session for the name', () => {
    mockExec.mockReturnValue(Buffer.from(''))
    killSession('web_x')
    expect(mockExec).toHaveBeenCalledWith('tmux', ['kill-session', '-t', 'web_x'], { stdio: 'ignore' })
  })

  it('swallows errors when the session is already gone', () => {
    mockExec.mockImplementation(() => {
      throw new Error('no session')
    })
    expect(() => killSession('web_gone')).not.toThrow()
  })
})
