import { stripVTControlCharacters } from "util";
import { stderr, stdout } from "../../internal/logging";
import { mockTestWrapSigInt } from "./mockTestWrapSigInt";

/**
 * Intercepts stdout/stderr from logging module.
 */
export function mockTestStd(): {
  stdout: string;
  stderr: string;
  out: string;
  print: () => void;
} {
  const stdoutBufs: Buffer[] = [];
  const stderrBufs: Buffer[] = [];
  const outBufs: Buffer[] = [];

  for (const [std, bufs] of [
    [stdout, stdoutBufs],
    [stderr, stderrBufs],
  ] as const) {
    jest.spyOn(std, "write").mockImplementation((chunk, ...args: any[]) => {
      chunk = typeof chunk === "string" ? Buffer.from(chunk) : chunk;
      bufs.push(chunk);
      outBufs.push(chunk);
      args.find((arg) => typeof arg === "function")?.(null);
      return true;
    });
  }

  mockTestWrapSigInt();

  return {
    get stdout() {
      return stripVTControlCharacters(
        Buffer.concat(stdoutBufs as Uint8Array[]).toString(),
      );
    },
    get stderr() {
      return stripVTControlCharacters(
        Buffer.concat(stderrBufs as Uint8Array[]).toString(),
      );
    },
    get out() {
      return stripVTControlCharacters(
        Buffer.concat(outBufs as Uint8Array[]).toString(),
      );
    },
    print() {
      // eslint-disable-next-line no-console
      console.log(this.out);
    },
  };
}
