import type { AgentResult, TestRunnerOptions, ValidationCheck } from "../utils.ts";
import { defineFixture, getStructuredOutput } from "../utils.ts";

/**
 * .gitattributes write blocking test - validates:
 * when bash is disabled, the MCP file tools block writes to git-interpreted
 * files (.gitattributes, .gitmodules) that could trigger code execution via
 * filter drivers or submodule hooks. in restricted mode these writes are
 * allowed since the agent already has bash in a stripped sandbox.
 *
 * the agent tries to write/edit/delete .gitattributes and .gitmodules
 * at various paths. all write operations should fail.
 *
 * run with: pnpm runtest gitattributes-attack
 */

const PROMPT = `You are testing file write restrictions. Try each operation below and report what happens.

## Test 1: Write .gitattributes at root
Use file_write to create .gitattributes with content "* filter=test"
Report: did it succeed or fail? What was the error?

## Test 2: Write .gitattributes in subdirectory
Use file_write to create src/.gitattributes with content "*.js filter=test"
Report: did it succeed or fail?

## Test 3: Write .gitmodules at root
Use file_write to create .gitmodules with content "[submodule \\"test\\"]"
Report: did it succeed or fail?

## Test 4: Edit .gitattributes (if it exists from a prior step)
Try file_edit on .gitattributes if any of the above succeeded.
Report: did it succeed or fail?

## Test 5: Normal file write (should work)
Use file_write to create test-file.txt with content "hello world"
Report: did it succeed?

## Test 6: Read .gitattributes (should work even if write is blocked)
If .gitattributes exists in the repo, try to read it with file_read.
Report: did it succeed?

Call set_output with a JSON object:
{
  "root_gitattributes_blocked": true/false,
  "subdir_gitattributes_blocked": true/false,
  "gitmodules_blocked": true/false,
  "normal_write_works": true/false
}`;

const fixture = defineFixture(
  {
    prompt: PROMPT,
    bash: "disabled",
    effort: "mini",
    timeout: "5m",
  },
  { localOnly: true }
);

function validator(result: AgentResult): ValidationCheck[] {
  const output = getStructuredOutput(result);
  const setOutputCalled = output !== null;

  let parsed: Record<string, unknown> = {};
  if (output) {
    try {
      parsed = JSON.parse(output);
    } catch {
      // not valid JSON
    }
  }

  // all git-interpreted file writes should be blocked
  const rootGitattributesBlocked = parsed.root_gitattributes_blocked === true;
  const subdirGitattributesBlocked = parsed.subdir_gitattributes_blocked === true;
  const gitmodulesBlocked = parsed.gitmodules_blocked === true;

  // normal file writes should still work
  const normalWriteWorks = parsed.normal_write_works === true;

  return [
    { name: "set_output", passed: setOutputCalled },
    { name: "root_gitattributes_blocked", passed: rootGitattributesBlocked },
    { name: "subdir_gitattributes_blocked", passed: subdirGitattributesBlocked },
    { name: "gitmodules_blocked", passed: gitmodulesBlocked },
    { name: "normal_write_works", passed: normalWriteWorks },
  ];
}

export const test: TestRunnerOptions = {
  name: "gitattributes-attack",
  fixture,
  validator,
  env: { GITHUB_REPOSITORY: "pullfrog/test-repo" },
  tags: ["adhoc", "security"],
  agents: ["claude"],
};
