import * as fs from 'node:fs';
import * as path from 'node:path';
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
import { TasksFileSchema, serializeTasksFileData } from './schema.js';
import { createLogger } from '../../shared/utils/index.js';
const log = createLogger('task-store');
export class TaskStore {
    projectDir;
    tasksFile;
    taktDir;
    locked = false;
    constructor(projectDir) {
        this.projectDir = projectDir;
        this.taktDir = path.join(projectDir, '.takt');
        this.tasksFile = path.join(this.taktDir, 'tasks.yaml');
    }
    getTasksFilePath() {
        return this.tasksFile;
    }
    ensureDirs() {
        fs.mkdirSync(this.taktDir, { recursive: true });
    }
    read() {
        return this.withLock(() => this.readUnsafe());
    }
    update(mutator) {
        return this.withLock(() => {
            const current = this.readUnsafe();
            const updated = TasksFileSchema.parse(mutator(current));
            this.writeUnsafe(updated);
            return updated;
        });
    }
    readUnsafe() {
        this.ensureDirs();
        if (!fs.existsSync(this.tasksFile)) {
            return { tasks: [] };
        }
        let raw;
        try {
            raw = fs.readFileSync(this.tasksFile, 'utf-8');
        }
        catch (err) {
            log.error('Failed to read tasks file', { file: this.tasksFile, error: String(err) });
            throw err;
        }
        try {
            const parsed = parseYaml(raw);
            return TasksFileSchema.parse(parsed);
        }
        catch (err) {
            log.error('tasks.yaml is broken. Keeping file untouched.', { file: this.tasksFile, error: String(err) });
            const reason = err instanceof Error ? err.message : String(err);
            throw new Error(`Invalid tasks.yaml: ${this.tasksFile}. Please fix the file and retry. Cause: ${reason}`);
        }
    }
    writeUnsafe(state) {
        this.ensureDirs();
        const tempPath = `${this.tasksFile}.tmp-${process.pid}-${Date.now()}`;
        const yaml = stringifyYaml(serializeTasksFileData(state));
        fs.writeFileSync(tempPath, yaml, 'utf-8');
        fs.renameSync(tempPath, this.tasksFile);
    }
    withLock(fn) {
        if (this.locked) {
            throw new Error('TaskStore: reentrant lock detected');
        }
        this.locked = true;
        try {
            return fn();
        }
        finally {
            this.locked = false;
        }
    }
}
//# sourceMappingURL=store.js.map