import { describe, it, expect } from 'vitest';
import { join } from 'node:path';
import { logRoot, spaceRunsDir, spaceConflictDir, resolveReporterRuntimeDir } from './runtime-paths.js';

describe('runtime-paths (計画5)', () => {
  describe('logRoot', () => {
    it('runtime_dir が指定されていればそれを返す', () => {
      expect(logRoot({ runtimeDir: '/wt/space/s1/runs/42', workspacePath: '/wt/space/s1/files' }))
        .toBe('/wt/space/s1/runs/42');
    });

    it('runtimeDir が null/undefined なら workspacePath/logs を返す（後方互換）', () => {
      expect(logRoot({ runtimeDir: null, workspacePath: '/wt/local/42' }))
        .toBe(join('/wt/local/42', 'logs'));
      expect(logRoot({ workspacePath: '/wt/local/42' }))
        .toBe(join('/wt/local/42', 'logs'));
    });

    it('両方欠けていても安全にフォールバックする', () => {
      expect(logRoot({})).toBe(join('.', 'logs'));
    });
  });

  describe('spaceRunsDir / spaceConflictDir', () => {
    it('runs/{taskId} を組み立てる', () => {
      expect(spaceRunsDir('/wt', 's1', 42)).toBe(join('/wt', 'space', 's1', 'runs', '42'));
    });
    it('.conflict は files の外に置く', () => {
      expect(spaceConflictDir('/wt', 's1')).toBe(join('/wt', 'space', 's1', '.conflict'));
    });
  });

  describe('resolveReporterRuntimeDir (Opus P1)', () => {
    it('persistent スペースタスクは local_task の runtime_dir を優先する', () => {
      const runs = spaceRunsDir('/wt', 's1', 42);
      expect(resolveReporterRuntimeDir({ jobRuntimeDir: null, localTaskRuntimeDir: runs }))
        .toBe(runs);
    });

    it('local_task の runtime_dir が無ければ job の runtime_dir にフォールバックする', () => {
      expect(resolveReporterRuntimeDir({ jobRuntimeDir: '/wt/job-runtime', localTaskRuntimeDir: null }))
        .toBe('/wt/job-runtime');
    });

    it('両方 null なら undefined（ephemeral / legacy / gitea-issue は workspacePath/logs にフォールバック）', () => {
      expect(resolveReporterRuntimeDir({ jobRuntimeDir: null, localTaskRuntimeDir: null }))
        .toBeUndefined();
      expect(resolveReporterRuntimeDir({})).toBeUndefined();
    });

    it('reader (logRoot) と同じ dir を指す — writer/reader が一致する', () => {
      const runs = spaceRunsDir('/wt', 's1', 42);
      // writer 側: reporter に渡す runtime_dir
      const writerDir = resolveReporterRuntimeDir({ jobRuntimeDir: null, localTaskRuntimeDir: runs });
      // reader 側: file API の logs セクション = logRoot(task)
      const readerDir = logRoot({ runtimeDir: runs, workspacePath: '/wt/space/s1/files' });
      expect(writerDir).toBe(readerDir);
    });

    it('runtime_dir null の既存タスクは writer/reader とも workspacePath/logs に一致する（後方互換）', () => {
      const workspacePath = '/wt/local/42';
      const writerDir = resolveReporterRuntimeDir({ jobRuntimeDir: null, localTaskRuntimeDir: null });
      // writer undefined → reporter は workspacePath/logs にフォールバック
      const writerEffective = writerDir ?? join(workspacePath, 'logs');
      const readerDir = logRoot({ runtimeDir: null, workspacePath });
      expect(writerEffective).toBe(readerDir);
      expect(writerEffective).toBe(join(workspacePath, 'logs'));
    });
  });
});
