import axios from "axios";
import { Request, Response } from "express";
import { Route, RouteMessages } from "server";
import { PROXY_SECRET } from "../secrets";

export default class ProxyRoute extends Route {
  constructor() {
    super({ path: "/proxy" });
  }

  async handle(req: Request, res: Response) {
    const before = Date.now();
    const json = req.body;
    const secret = json.secret;
    if (!secret) {
      res.status(401).json(RouteMessages.badRequest("No secret provided"));
      return;
    }
    if (secret !== PROXY_SECRET) {
      res.status(401).json(RouteMessages.badRequest("Invalid secret"));
      return;
    }

    const url = json.url;
    if (!url) {
      res.status(400).json(RouteMessages.badRequest("No URL provided"));
      return;
    }
    try {
      const response = await axios.get(url);
      const data = response.data;
      const headers = response.headers;

      // Is delete the best way to do this??
      // Remove CORS headers
      delete headers["access-control-allow-origin"];
      delete headers["access-control-allow-credentials"];
      delete headers["access-control-allow-headers"];
      delete headers["access-control-allow-methods"];
      delete headers["access-control-expose-headers"];
      delete headers["cross-origin-embedder-policy"];
      delete headers["cross-origin-opener-policy"];
      delete headers["cross-origin-resource-policy"];

      // Cloudflare headers
      delete headers["server"];
      delete headers["nel"];
      delete headers["report-to"];
      delete headers["cf-cache-status"];
      delete headers["cf-ray"];
      delete headers["alt-svc"];

      // Misc headers
      delete headers["transfer-encoding"];
      delete headers["content-security-policy"];
      delete headers["strict-transport-security"];
      delete headers["referrer-policy"];

      // Add node specific headers
      headers["x-proxy-node"] = process.env.NODE_ID;
      headers["x-proxy-response-time"] = Date.now() - before + "ms";

      // Add CORS headers
      headers["access-control-allow-origin"] = "*";
      headers["access-control-allow-methods"] = "*";

      // Return the JSON response
      res.status(response.status).set(headers).send(data);
    } catch (ex) {
      res
        .status(500)
        .json(RouteMessages.internalServerError("Error fetching URL"));
    }
  }
}