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

import {
  buildPluginSpawnEnv,
  PLUGIN_SPAWN_ENV_KEYS,
  rewriteClaudePaths,
} from '../claudeCompat.js'

describe('rewriteClaudePaths', () => {
  it('rewrites ~/.claude/ to ~/.sandcode/', () => {
    expect(rewriteClaudePaths('cat ~/.claude/settings.json')).toBe(
      'cat ~/.sandcode/settings.json',
    )
  })

  it('rewrites ~/.claude.json to ~/.sandcode.json', () => {
    expect(rewriteClaudePaths('jq . ~/.claude.json')).toBe('jq . ~/.sandcode.json')
  })

  it('rewrites $HOME/.claude/ and ${HOME}/.claude/', () => {
    expect(rewriteClaudePaths('ls $HOME/.claude/commands')).toBe(
      'ls $HOME/.sandcode/commands',
    )
    expect(rewriteClaudePaths('ls ${HOME}/.claude/commands')).toBe(
      'ls ${HOME}/.sandcode/commands',
    )
  })

  it('rewrites $CLAUDE_CONFIG_DIR to $SANDCODE_CONFIG_DIR', () => {
    expect(rewriteClaudePaths('path=$CLAUDE_CONFIG_DIR/hooks')).toBe(
      'path=$SANDCODE_CONFIG_DIR/hooks',
    )
    expect(rewriteClaudePaths('path=${CLAUDE_CONFIG_DIR}/hooks')).toBe(
      'path=${SANDCODE_CONFIG_DIR}/hooks',
    )
  })

  it('does NOT rewrite prose or unrelated words containing "claude"', () => {
    expect(rewriteClaudePaths('claude is an assistant')).toBe(
      'claude is an assistant',
    )
    expect(rewriteClaudePaths('my-claude-tool')).toBe('my-claude-tool')
    // `.claude` embedded inside a larger identifier must stay put
    expect(rewriteClaudePaths('xclaude.claude.json')).toBe('xclaude.claude.json')
  })

  it('does NOT rewrite absolute /path/.claude — only anchored forms', () => {
    expect(rewriteClaudePaths('/usr/local/.claude/cfg')).toBe(
      '/usr/local/.claude/cfg',
    )
  })

  it('handles several substitutions in one string', () => {
    const input = 'cp ~/.claude/settings.json $HOME/.claude.json'
    expect(rewriteClaudePaths(input)).toBe(
      'cp ~/.sandcode/settings.json $HOME/.sandcode.json',
    )
  })
})

describe('buildPluginSpawnEnv', () => {
  it('seeds SANDCODE_* and CLAUDE_* PLUGIN_ROOT aliases', () => {
    const env = buildPluginSpawnEnv({ pluginPath: '/tmp/p' })
    expect(env.SANDCODE_PLUGIN_ROOT).toBe('/tmp/p')
    expect(env.CLAUDE_PLUGIN_ROOT).toBe('/tmp/p')
  })

  it('includes PLUGIN_DATA aliases only when supplied', () => {
    expect(buildPluginSpawnEnv({ pluginPath: '/tmp/p' }).SANDCODE_PLUGIN_DATA).toBeUndefined()
    const env = buildPluginSpawnEnv({ pluginPath: '/tmp/p', pluginData: '/tmp/d' })
    expect(env.SANDCODE_PLUGIN_DATA).toBe('/tmp/d')
    expect(env.CLAUDE_PLUGIN_DATA).toBe('/tmp/d')
  })

  it('exposes CLAUDE_CONFIG_DIR when SANDCODE_CONFIG_DIR is set', () => {
    const prev = process.env.SANDCODE_CONFIG_DIR
    process.env.SANDCODE_CONFIG_DIR = '/tmp/cfg'
    try {
      const env = buildPluginSpawnEnv({ pluginPath: '/tmp/p' })
      expect(env.CLAUDE_CONFIG_DIR).toBe('/tmp/cfg')
    } finally {
      if (prev === undefined) delete process.env.SANDCODE_CONFIG_DIR
      else process.env.SANDCODE_CONFIG_DIR = prev
    }
  })

  it('all produced keys are a subset of PLUGIN_SPAWN_ENV_KEYS', () => {
    const env = buildPluginSpawnEnv({ pluginPath: '/tmp/p', pluginData: '/tmp/d' })
    for (const k of Object.keys(env)) {
      expect(PLUGIN_SPAWN_ENV_KEYS.has(k)).toBe(true)
    }
  })
})
