import { expect } from "e2e";
import { execFileSync } from "node:child_process";
import { writeFileSync } from "node:fs";
import { request } from "node:http";
import { test, WEB } from "./t3.ts";

const scratch = process.env.FORK_PR_FIXTURE_DIR!;
test("Create a PR from a fork into gh's resolved upstream base", WEB, async ({t3, app, screen, browser}) => {
  await new Promise<void>((resolve,reject)=>{const r=request({socketPath:scratch+"/api.sock",path:"/reset",method:"POST"},res=>{res.resume();res.on("end",resolve)});r.on("error",reject);r.end();});
  const repo = await t3.project("Fork PR demonstration");
  const git=(...args:string[])=>execFileSync("git",args,{cwd:repo,encoding:"utf8"});
  execFileSync("git",["init","--bare",repo+"-fork.git"]);
  git("remote","add","origin","https://github.com/octocat/codething-mvp.git");
  git("remote","add","upstream","https://github.com/pingdotgg/codething-mvp.git");
  git("config","url."+repo+"-fork.git.insteadOf","https://github.com/octocat/codething-mvp.git");
  git("config","remote.upstream.gh-resolved","base");
  git("push","origin","main");
  git("symbolic-ref","refs/remotes/origin/HEAD","refs/remotes/origin/main");
  git("checkout","-b","feature/fork-only");
  writeFileSync(repo+"/feature.txt","A small feature from the fork.\n");
  git("add","feature.txt");
  git("-c","user.name=Scenario","-c","user.email=scenario@example.invalid","commit","-m","Add fork-only feature");
  git("push","-u","origin","feature/fork-only");
  await t3.open();
  await expect(screen.getByRole("button", "Create PR")).toBeVisible({timeout: 120_000});
  await screen.getByRole("button", "Create PR").tap();
  await expect(screen.getByText(/Created PR|Action failed/)).toBeVisible();
  await browser.evaluate(async () => { await Promise.all(document.getAnimations().filter(a => a.effect?.getTiming().iterations !== Infinity).map(a => a.finished.catch(() => {}))); });
  let previous: Buffer | undefined;
  for (let i = 0; i < 8; i++) {
    const shot = await app.screenshot(`fork-pr-result-${i}`);
    const pixels = execFileSync("convert", [shot, "rgba:-"], {maxBuffer: 10_000_000});
    if (previous?.equals(pixels)) break;
    if (i === 7) throw new Error("The evidence frame did not settle");
    previous = pixels;
    await new Promise(resolve => setTimeout(resolve, 500));
  }
  await expect(screen.getByText("Created PR",{exact:false})).toBeVisible();
});
