import { homedir } from 'node:os';
import { join } from 'node:path';
import { readFile, readdir } from 'node:fs/promises';
import { parseMemoryEntries, type MemoryEntry } from "./entries.js";
import { getMemoryRoot } from './paths.js';

export interface MemoryScope {
  projectRoot: string;
  sessionDir?: string;
  homeDir?: string;
}

async function scanDirectory(dir: string): Promise<MemoryEntry[]> {
  const entries: MemoryEntry[] = [];
  try {
    const files = await readdir(dir, { withFileTypes: true });
    for (const file of files) {
      if (file.isFile() && file.name.endsWith('.md')) {
        const content = await readFile(join(dir, file.name), 'utf8');
        entries.push(...parseMemoryEntries(file.name, content));
      }
    }
  } catch {
    // Directory doesn't exist
  }
  return entries;
}

const MEMORY_TOPICS = ['project', 'user', 'reference'] as const;

async function scanTopicDirs(root: string): Promise<MemoryEntry[]> {
  const entries: MemoryEntry[] = [];
  for (const topic of MEMORY_TOPICS) {
    entries.push(...(await scanDirectory(join(root, topic))));
  }
  return entries;
}

export async function scanMemoryScopes(scope: MemoryScope): Promise<MemoryEntry[]> {
  const allEntries: MemoryEntry[] = [];

  // 1. Global (~/.boocode/memory/) - lowest priority
  allEntries.push(...(await scanTopicDirs(getMemoryRoot(homedir()))));

  // 2. Home ($HOME/.boocode/memory)
  const homeDir = scope.homeDir ?? homedir();
  const homeRoot = getMemoryRoot(homeDir);
  if (homeRoot !== getMemoryRoot(homedir())) {
    allEntries.push(...(await scanTopicDirs(homeRoot)));
  }

  // 3. Project (.boocode/memory/ under project root)
  allEntries.push(...(await scanTopicDirs(getMemoryRoot(scope.projectRoot))));

  // 4. Session (.boocode/sessions/<id>/memory.md) - highest priority
  if (scope.sessionDir) {
    try {
      const sessionFile = join(scope.sessionDir, 'memory.md');
      const content = await readFile(sessionFile, 'utf8');
      allEntries.push(...parseMemoryEntries('session-memory', content));
    } catch {
      // No session memory file
    }
  }

  return allEntries;
}

export async function scanProjectMemory(projectRoot: string): Promise<MemoryEntry[]> {
  return scanMemoryScopes({ projectRoot });
}
