// src/install/blocks/WrapperScriptInstaller.ts
import { existsSync, lstatSync, readlinkSync, symlinkSync, unlinkSync, mkdirSync } from "node:fs";
import { dirname } from "node:path";
import type { StepReceipt } from "../Installer";

export type WrapperReceipt = Extract<StepReceipt, { kind: "wrapper" }>;

export class WrapperScriptInstaller {
  constructor(
    private readonly symlink: string,
    private readonly target: string,
  ) {}

  async apply(): Promise<WrapperReceipt> {
    let existed = false;
    let priorTarget: string | null = null;

    try {
      const stat = lstatSync(this.symlink);
      existed = true;
      if (stat.isSymbolicLink()) {
        priorTarget = readlinkSync(this.symlink);
        unlinkSync(this.symlink);
      }
    } catch {
      // file does not exist
    }

    mkdirSync(dirname(this.symlink), { recursive: true });
    symlinkSync(this.target, this.symlink);

    return {
      kind: "wrapper",
      symlink: this.symlink,
      existedBefore: existed,
      priorTarget,
    };
  }

  async revert(receipt: WrapperReceipt): Promise<void> {
    try {
      const stat = lstatSync(this.symlink);
      if (stat.isSymbolicLink()) unlinkSync(this.symlink);
    } catch {
      // already gone
    }
    if (receipt.priorTarget !== null) {
      symlinkSync(receipt.priorTarget, this.symlink);
    }
  }
}
