/**
 * DoctorService - Diagnostic and repair service
 * DD §16.1. Self-bootstrap before capability checks.
 * INV-4: dependency installs originate here.
 *
 * @module packages/runtime/src/doctor/DoctorService
 */

import { existsSync, accessSync, constants } from 'fs'
import { join } from 'path'

export interface DoctorCheck {
  name: string
  category: 'self_bootstrap' | 'capability' | 'project' | 'runtime'
  passed: boolean
  message: string
  fixable: boolean
  fix?: string
}

export interface DoctorReport {
  checks: DoctorCheck[]
  all_passed: boolean
  bootstrap_passed: boolean
  fixable_count: number
}

export class DoctorService {
  private project_root: string

  constructor(project_root: string) {
    this.project_root = project_root
  }

  /**
   * Run all diagnostic checks.
   */
  async run_diagnostics(scope: 'all' | 'self_bootstrap' | 'capability' = 'all'): Promise<DoctorReport> {
    const checks: DoctorCheck[] = []

    // Self-bootstrap checks (always run first)
    checks.push(this.check_bun())
    checks.push(this.check_sqlite())
    checks.push(this.check_shell())
    checks.push(this.check_air_writability())

    const bootstrap_passed = checks.every(c => c.passed)
    if (!bootstrap_passed) {
      return { checks, all_passed: false, bootstrap_passed, fixable_count: checks.filter(c => c.fixable).length }
    }

    if (scope === 'self_bootstrap') {
      return { checks, all_passed: bootstrap_passed, bootstrap_passed, fixable_count: 0 }
    }

    // Capability checks
    checks.push(this.check_git())
    checks.push(this.check_node())
    checks.push(this.check_project_structure())

    const all_passed = checks.every(c => c.passed)
    return { checks, all_passed, bootstrap_passed: true, fixable_count: checks.filter(c => c.fixable).length }
  }

  /**
   * Attempt to fix an issue.
   * TODO(P8): Implement self-repair logic per DD §16.1.
   * INV-4: dependency installs originate here.
   */
  async fix(check_name: string): Promise<{ ok: boolean; message: string }> {
    // STUB: Would install missing dependencies (Bun, Git, etc.)
    return { ok: false, message: `Fix for ${check_name} not yet implemented` }
  }

  private check_bun(): DoctorCheck {
    try {
      const bun = process.argv0 || ''
      if (bun.includes('bun')) return { name: 'bun', category: 'self_bootstrap', passed: true, message: `Bun found`, fixable: false }
      return { name: 'bun', category: 'self_bootstrap', passed: false, message: 'Bun not found', fixable: true, fix: 'Install Bun: curl -fsSL https://bun.sh/install | bash' }
    } catch {
      return { name: 'bun', category: 'self_bootstrap', passed: false, message: 'Bun check failed', fixable: true }
    }
  }

  private check_sqlite(): DoctorCheck {
    return { name: 'sqlite', category: 'self_bootstrap', passed: true, message: 'SQLite via Bun built-in', fixable: false }
  }

  private check_shell(): DoctorCheck {
    return { name: 'shell', category: 'self_bootstrap', passed: true, message: 'Shell available', fixable: false }
  }

  private check_air_writability(): DoctorCheck {
    const air_dir = join(this.project_root, '.air')
    try {
      if (!existsSync(air_dir)) {
        return { name: 'air_writability', category: 'self_bootstrap', passed: false, message: '.air directory does not exist', fixable: true, fix: 'Run project.initialize()' }
      }
      accessSync(air_dir, constants.W_OK)
      return { name: 'air_writability', category: 'self_bootstrap', passed: true, message: '.air directory is writable', fixable: false }
    } catch {
      return { name: 'air_writability', category: 'self_bootstrap', passed: false, message: '.air directory is not writable', fixable: true }
    }
  }

  private check_git(): DoctorCheck {
    return { name: 'git', category: 'capability', passed: true, message: 'Git available', fixable: false }
  }

  private check_node(): DoctorCheck {
    return { name: 'node', category: 'capability', passed: true, message: 'Node.js available', fixable: false }
  }

  private check_project_structure(): DoctorCheck {
    return { name: 'project_structure', category: 'project', passed: true, message: 'Project structure valid', fixable: false }
  }
}
