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 stdoutBuf: Buffer[] = [];
  const stderrBuf: Buffer[] = [];
  const outBuf: Buffer[] = [];

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

  mockTestWrapSigInt();

  return {
    get stdout() {
      return stripVTControlCharacters(Buffer.concat(stdoutBuf).toString());
    },
    get stderr() {
      return stripVTControlCharacters(Buffer.concat(stderrBuf).toString());
    },
    get out() {
      return stripVTControlCharacters(Buffer.concat(outBuf).toString());
    },
    print() {
      // eslint-disable-next-line no-console
      console.log(this.out);
    },
  };
}
