import path from "path";
import { Polly, PollyConfig } from "@pollyjs/core";
// @ts-ignore polly's typings aren't great but we don't really need them for this small init code
import { setupPolly } from "setup-polly-jest";
import { MODES } from "@pollyjs/utils";
import { env } from "@src/env";

Polly.register(require("@pollyjs/adapter-node-http"));
Polly.register(require("@pollyjs/persister-fs"));

const config: PollyConfig = {
  adapters: ["node-http"],
  persister: "fs",
  persisterOptions: {
    fs: {
      recordingsDir: path.resolve(__dirname, "../tests/__recordings__"),
    },
  },
  matchRequestsBy: {
    body(body: string): string {
      return stripSecrets(body);
    },
    headers(headers: Record<string, string>): Record<string, string> {
      // If our real/for-recording secrets are different lengths than our fake/for-checkin secrets, content length will be off
      delete headers["content-length"];
      // The user agent has node version + OS version in it.
      delete headers["user-agent"];
      Object.entries(headers).forEach(([key, value]) => {
        headers[key] = stripSecrets(value);
      });
      return headers;
    },
  },
  logging: true,
  mode: MODES.REPLAY,
};

const context = setupPolly(config);

// Polly doesn't save the "matchRequestsBy" logic, so manually re-apply it. See https://github.com/Netflix/pollyjs/issues/251#issuecomment-531578600
beforeEach(() => {
  const polly = context.polly as Polly;
  polly.server.any().on("beforePersist", (req, entry) => {
    entry.request.postData.text = stripSecrets(entry.request.postData.text);
    entry.request.headers.forEach((h: any) => {
      if (typeof h.value === "string") {
        h.value = stripSecrets(h.value);
      }
    });
  });
});

function stripSecrets(body: string): string {
  return body
    .replace(env.SLACK_TOKEN, "...")
    .replace(env.SFDC_PASSWORD, "...")
    .replace(env.SENDGRID_API_KEY, "...");
}