// Repro driver for pingdotgg/t3code#25398: runs the real prunePinnedRuntimes on Linux
// (real filesystem, real /proc scan) against a synthetic T3 home.
import * as NodeServices from "@effect/platform-node/NodeServices";
import * as Effect from "effect/Effect";
import * as FileSystem from "effect/FileSystem";
import * as Path from "effect/Path";
import * as HostProcess from "@t3tools/shared/HostProcess";

const root = process.argv[2]!;
const { prunePinnedRuntimes } = await import(`${root}/apps/server/src/cloud/pinnedRuntime.ts`);
const ProcessRunner = await import(`${root}/apps/server/src/processRunner.ts`);

const program = Effect.gen(function* () {
  const fs = yield* FileSystem.FileSystem;
  const path = yield* Path.Path;
  const home = yield* fs.makeTempDirectoryScoped({ prefix: "t3-25398-" });
  const versionsDir = path.join(home, "runtime", "versions");
  const binDir = path.join(home, "bin");
  const launchers = path.join(home, "runtime", "launchers");
  yield* fs.makeDirectory(binDir, { recursive: true });
  const install = (version: string) =>
    Effect.gen(function* () {
      const dir = path.join(versionsDir, version);
      yield* fs.makeDirectory(dir, { recursive: true });
      yield* fs.writeFileString(path.join(dir, "t3"), "#!/bin/sh\n");
      const sentinel = path.join(dir, ".install-complete");
      yield* fs.writeFileString(sentinel, `${version}\n`);
      yield* fs.utimes(sentinel, 0, 0); // installed long ago: past the one-hour grace
    });
  const show = (label: string) =>
    Effect.gen(function* () {
      const versions = (yield* fs.readDirectory(versionsDir)).sort();
      const recorded = yield* fs.readFileString(launchers).pipe(Effect.orElseSucceed(() => ""));
      console.log(`${label}`);
      console.log(`  versions/:  ${versions.join(", ")}`);
      console.log(
        `  launchers:  ${recorded.trim().split("\n").filter(Boolean).map((l) => l.replace(home, "$HOME")).join(" | ") || "(empty)"}`,
      );
    });
  const prune = (keep: string, pathDir: string) =>
    prunePinnedRuntimes({ baseDir: home, keep: [keep] }).pipe(
      Effect.provideService(HostProcess.Environment, {
        T3CODE_INSTALL_BIN_DIR: binDir,
        PATH: `${path.join(versionsDir, pathDir)}:/usr/bin:/bin`,
      }),
      Effect.tap((removed: string[]) =>
        Effect.sync(() => console.log(`  prune(keep=${keep}, service PATH has versions/${pathDir}) removed: [${removed.join(", ")}]`)),
      ),
    );

  console.log(`platform=${process.platform} node=${process.version}`);
  // Step 1-2: service installed on 0.1.0; its PATH includes versions/0.1.0. Startup prune.
  yield* install("0.1.0");
  yield* fs.symlink(path.join(versionsDir, "0.1.0", "t3"), path.join(binDir, "t3"));
  yield* show("step 1: service on 0.1.0");
  yield* prune("0.1.0", "0.1.0");
  yield* show("after startup prune on 0.1.0");
  // Step 3-4: t3 update to 0.1.2 (launcher repointed), service reinstalled; PATH now has versions/0.1.2.
  yield* install("0.1.2");
  yield* fs.remove(path.join(binDir, "t3"));
  yield* fs.symlink(path.join(versionsDir, "0.1.2", "t3"), path.join(binDir, "t3"));
  yield* prune("0.1.2", "0.1.2");
  yield* show("after startup prune on 0.1.2 (expected: 0.1.0 removed)");
});

await Effect.runPromise(
  program.pipe(Effect.scoped, Effect.provide(ProcessRunner.layer), Effect.provide(NodeServices.layer)),
);
