/**
 * ProjectStore - Locate, initialize, and open projects
 *
 * Implements ProjectStore contract (contracts §8.3) per DD §6.1.
 *
 * @module packages/runtime/src/project/ProjectStore
 */

import { existsSync } from 'fs'
import { join } from 'path'

import type { ProjectContext, ProjectInitOptions, ProjectStore as IProjectStore } from '@aircoding/contracts'

import { ProjectLocator, createProjectLocator } from './ProjectLocator.js'
import { ProjectInitializer, createProjectInitializer } from './ProjectInitializer.js'

/**
 * ProjectStore implements the ProjectStore contract:
 * - locate(start_path) → finds .air/shared/project.json
 * - initialize() → creates .air/shared + .air/local, generates project_id
 * - open() → loads ProjectContext
 */
export class ProjectStore implements IProjectStore {
  private locator: ProjectLocator
  private initializer: ProjectInitializer

  constructor() {
    this.locator = createProjectLocator()
    this.initializer = createProjectInitializer()
  }

  async locate(startPath: string): Promise<ProjectContext | undefined> {
    return this.locator.locate(startPath)
  }

  async initialize(projectRoot: string, options?: ProjectInitOptions): Promise<ProjectContext> {
    return this.initializer.initialize(projectRoot, options)
  }

  async open(projectRoot: string): Promise<ProjectContext> {
    const sharedProjectJson = join(projectRoot, '.air', 'shared', 'project.json')

    if (!existsSync(sharedProjectJson)) {
      throw new Error(
        `Project not found at ${projectRoot}. Run initialize() first or provide a valid project path.`
      )
    }

    const context = this.locator.locate(projectRoot)
    if (!context) {
      throw new Error(`Failed to load project context from ${projectRoot}`)
    }

    return context
  }
}

export function createProjectStore(): ProjectStore {
  return new ProjectStore()
}