import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { randomUUID } from 'node:crypto';
import { Repository } from './repository.js';

function freshRepo(): { repo: Repository; dir: string } {
  const dir = mkdtempSync(join(tmpdir(), 'tool-policy-test-'));
  const repo = new Repository(join(dir, `${randomUUID()}.db`));
  return { repo, dir };
}

describe('space tool_policy persistence', () => {
  let repo: Repository;
  let dir: string;

  beforeEach(() => {
    ({ repo, dir } = freshRepo());
  });

  afterEach(() => {
    rmSync(dir, { recursive: true, force: true });
  });

  it('defaults to null for a new space', async () => {
    const space = await repo.createSpace({
      kind: 'case',
      title: 'テスト案件',
      ownerId: 'user-1',
      visibility: 'private',
    });
    expect(repo.getSpaceToolPolicy(space.id)).toBeNull();
  });

  it('round-trips JSON through setSpaceToolPolicy / getSpaceToolPolicy', async () => {
    const space = await repo.createSpace({
      kind: 'case',
      title: 'Policy Space',
      ownerId: 'user-1',
      visibility: 'private',
    });
    const policy = { enabledSensitive: ['Bash', 'Write'] };
    repo.setSpaceToolPolicy(space.id, JSON.stringify(policy));
    const raw = repo.getSpaceToolPolicy(space.id);
    expect(raw).not.toBeNull();
    expect(JSON.parse(raw!)).toEqual(policy);
  });

  it('setSpaceToolPolicy(id, null) clears the policy', async () => {
    const space = await repo.createSpace({
      kind: 'case',
      title: 'Clearable Space',
      ownerId: 'user-1',
      visibility: 'private',
    });
    repo.setSpaceToolPolicy(space.id, '{"foo":1}');
    repo.setSpaceToolPolicy(space.id, null);
    expect(repo.getSpaceToolPolicy(space.id)).toBeNull();
  });

  it('tool_policy column exists in spaces table (schema dual-path check)', () => {
    // @ts-expect-error reach into private db handle to verify column exists
    const cols = repo.db.prepare("PRAGMA table_info('spaces')").all() as Array<{ name: string }>;
    expect(cols.map(c => c.name)).toContain('tool_policy');
  });
});
