// Scratch reproduction for issue 26577. Not for commit.
import * as NodeServices from "@effect/platform-node/NodeServices";
import { assert, it } from "@effect/vitest";
import * as Effect from "effect/Effect";
import * as Fiber from "effect/Fiber";
import * as FileSystem from "effect/FileSystem";
import * as Layer from "effect/Layer";
import * as Path from "effect/Path";

import * as ServerConfig from "../config.ts";
import * as GitVcsDriver from "./GitVcsDriver.ts";

const layerServerConfig = ServerConfig.layerTest(process.cwd(), { prefix: "t3-scratch-26577-" });
const layerTest = GitVcsDriver.layer.pipe(
  Layer.provide(layerServerConfig),
  Layer.provideMerge(NodeServices.layer),
);

const setup = Effect.gen(function* () {
  const fs = yield* FileSystem.FileSystem;
  const path = yield* Path.Path;
  const driver = yield* GitVcsDriver.GitVcsDriver;
  const parent = yield* fs.makeTempDirectoryScoped({ prefix: "scratch-26577-" });
  const cwd = path.join(parent, "repo");
  yield* fs.makeDirectory(cwd);
  const git = (args: string[]) =>
    driver.execute({ operation: "scratch", cwd, args, timeoutMs: 10_000 });
  yield* driver.initRepo({ cwd });
  yield* git(["config", "user.email", "t@t.com"]);
  yield* git(["config", "user.name", "T"]);
  yield* fs.writeFileString(path.join(cwd, "README.md"), "x\n");
  yield* git(["add", "."]);
  yield* git(["commit", "-m", "init"]);
  yield* git(["checkout", "-b", "feature-x"]);
  return { driver, cwd, git };
});

const createExisting = (driver: GitVcsDriver.GitVcsDriver["Service"], cwd: string) =>
  driver
    .createWorktree({
      cwd,
      refName: "HEAD",
      newRefName: "feature-x",
      baseRefName: "HEAD",
      path: null,
    })
    .pipe(Effect.flip);

  it.live("A: existing branch fails immediately", () =>
    Effect.gen(function* () {
      const { driver, cwd } = yield* setup;
      const t0 = Date.now();
      const error = yield* createExisting(driver, cwd);
      console.log("A elapsed ms", Date.now() - t0, error.reason, error.message);
      assert.equal(error.reason, "branch_already_exists");
    }).pipe(Effect.scoped, Effect.provide(layerTest)),
  );

  it.live("B: same call while 8 default-timeout git commands ignore SIGTERM", () =>
    Effect.gen(function* () {
      const { driver, cwd } = yield* setup;
      const hang = driver.execute({
        operation: "scratch.hang",
        cwd,
        args: ["-c", "alias.hang=!trap '' TERM; exec sleep 8", "hang"],
        timeoutMs: 1_000,
      });
      const t0 = Date.now();
      const holders = yield* Effect.forEach(
        Array.from({ length: 8 }),
        () =>
          hang.pipe(
            Effect.exit,
            Effect.tap((exit) =>
              Effect.sync(() => console.log("B holder done ms", Date.now() - t0, exit._tag)),
            ),
            Effect.forkChild,
          ),
      );
      yield* Effect.sleep("300 millis");
      const t1 = Date.now();
      const error = yield* createExisting(driver, cwd);
      console.log("B createWorktree elapsed ms", Date.now() - t1, error.reason);
      yield* Fiber.joinAll(holders);
    }).pipe(Effect.scoped, Effect.provide(layerTest)),
  );
