/**
 * ProjectLocator - Locates .air/shared/project.json by walking up from start_path
 *
 * Implements DD §6.1 "ProjectLocator.locate(start)" — upward search.
 * This is a minimal implementation. Full implementation requires Node.js types.
 *
 * @module packages/runtime/src/project/ProjectLocator
 */

import { readFileSync, existsSync, statSync } from 'fs'
import { join, dirname } from 'path'

import type { ProjectContext } from '@aircoding/contracts'

const AIR_DIR = '.air'
const SHARED_DIR = 'shared'
const PROJECT_FILE = 'project.json'

export interface ProjectLocatorOptions {
  maxDepth?: number
}

/**
 * ProjectLocator walks upward from start_path looking for .air/shared/project.json
 */
export class ProjectLocator {
  private maxDepth: number

  constructor(options: ProjectLocatorOptions = {}) {
    this.maxDepth = options.maxDepth ?? 20
  }

  /**
   * Locate a project by walking up from start_path.
   * Returns ProjectContext if found, undefined otherwise.
   */
  locate(startPath: string): ProjectContext | undefined {
    let currentPath = startPath
    let depth = 0

    while (depth < this.maxDepth) {
      if (!this.isDirectory(currentPath)) {
        return undefined
      }

      const airSharedPath = join(currentPath, AIR_DIR, SHARED_DIR, PROJECT_FILE)

      if (existsSync(airSharedPath)) {
        return this.loadProjectContext(airSharedPath, currentPath)
      }

      const parentPath = dirname(currentPath)
      if (parentPath === currentPath) {
        break
      }
      currentPath = parentPath
      depth++
    }

    return undefined
  }

  private isDirectory(dirPath: string): boolean {
    try {
      return statSync(dirPath).isDirectory()
    } catch {
      return false
    }
  }

  private loadProjectContext(projectJsonPath: string, projectRoot: string): ProjectContext {
    const content = readFileSync(projectJsonPath, 'utf-8')
    const projectJson = JSON.parse(content) as {
      project_id: string
      schema_version?: number
    }

    const airRoot = join(projectRoot, AIR_DIR)
    const sharedRoot = join(airRoot, SHARED_DIR)
    const localRoot = join(airRoot, 'local')

    return {
      project_id: projectJson.project_id,
      project_root: projectRoot,
      air_root: airRoot,
      shared_root: sharedRoot,
      local_root: localRoot,
      schema_version: projectJson.schema_version ?? 1,
    }
  }
}

export function createProjectLocator(options?: ProjectLocatorOptions): ProjectLocator {
  return new ProjectLocator(options)
}