const fs = require('fs');
const path = require('path');

/**
 * Python LSP adapter — Pyright.
 *
 * Pyright ships as both an npm package and a pip package. We default to a
 * global npm install so the `pyright` binary lands on `$PATH` — the consumer
 * (Claude Code's LSP tool) spawns it by name from `$PATH`, so a project-local
 * devDep under `node_modules/.bin/` (the pre-v3.33.1 behaviour) was never
 * reachable and the layer silently fell back to Grep. Users who already drive
 * Python via pip/uv can override with an overlay and a system-managed pyright.
 *
 * Detection signal: pyproject.toml, setup.py, setup.cfg, requirements.txt,
 * Pipfile, or a top-level .py source tree.
 */
class PythonAdapter {
  constructor(cwd = process.cwd()) { this.cwd = cwd; }

  get name() { return 'python'; }
  get label() { return 'Python (Pyright)'; }
  get binary() { return 'pyright'; }
  get installMode() { return 'npm-global'; }
  get npmPackage() { return 'pyright'; }

  installCommand() { return 'npm install -g pyright'; }
  // Functional probe; reachability on $PATH is checked by the installer via
  // `command -v` (mirrors how the consumer spawns the binary).
  verifyCommand() { return 'pyright --version'; }
  claudePluginId() { return 'pyright-lsp@claude-plugins-official'; }

  static detect(cwd = process.cwd()) {
    const markers = ['pyproject.toml', 'setup.py', 'setup.cfg', 'requirements.txt', 'Pipfile'];
    for (const m of markers) {
      if (fs.existsSync(path.join(cwd, m))) return true;
    }
    // Fallback: a `src/` or top-level *.py file is a strong enough signal.
    try {
      const entries = fs.readdirSync(cwd);
      if (entries.some(e => e.endsWith('.py'))) return true;
    } catch { /* ignore */ }
    return false;
  }
}

module.exports = PythonAdapter;
