import assert from "node:assert/strict";
import { after, beforeEach, test } from "node:test";
import { origemPublicaDoAdmin } from "./origem-publica.ts";

const guardadas = {
  NEXT_PUBLIC_ADMIN_BASE_URL: process.env.NEXT_PUBLIC_ADMIN_BASE_URL,
  ADMIN_BASE_URL: process.env.ADMIN_BASE_URL,
  NEXT_PUBLIC_ADMIN_URL: process.env.NEXT_PUBLIC_ADMIN_URL,
};

beforeEach(() => {
  delete process.env.NEXT_PUBLIC_ADMIN_BASE_URL;
  delete process.env.ADMIN_BASE_URL;
  delete process.env.NEXT_PUBLIC_ADMIN_URL;
});

after(() => {
  for (const [chave, valor] of Object.entries(guardadas)) {
    if (valor === undefined) delete process.env[chave];
    else process.env[chave] = valor;
  }
});

const pedido = (url: string, headers: Record<string, string> = {}) => new Request(url, { headers });

test("atras do proxy, vale o host encaminhado e nao o localhost interno", () => {
  const req = pedido("http://localhost:3000/api/suppliers/x/purchase-orders", {
    "x-forwarded-host": "admin.ktalogu.com.br",
    "x-forwarded-proto": "https",
    host: "localhost:3000",
  });
  assert.equal(origemPublicaDoAdmin(req), "https://admin.ktalogu.com.br");
});

test("sem x-forwarded-proto, dominio de verdade e https", () => {
  const req = pedido("http://localhost:3000/api/x", { "x-forwarded-host": "admin.ktalogu.com.br" });
  assert.equal(origemPublicaDoAdmin(req), "https://admin.ktalogu.com.br");
});

test("o proxy pode empilhar varios valores; vale o primeiro", () => {
  const req = pedido("http://localhost:3000/api/x", {
    "x-forwarded-host": "admin.ktalogu.com.br, interno.local",
    "x-forwarded-proto": "https,http",
  });
  assert.equal(origemPublicaDoAdmin(req), "https://admin.ktalogu.com.br");
});

test("sem cabecalho de proxy, vale o Host da requisicao", () => {
  const req = pedido("http://10.0.0.5/api/x", { host: "admin.ktalogu.com.br" });
  assert.equal(origemPublicaDoAdmin(req), "https://admin.ktalogu.com.br");
});

test("x-forwarded-proto http num dominio publico nao vale: o link e https", () => {
  /* O proprio Next preenche esse cabecalho com "http" quando o proxy nao
     mandou nenhum. Foi o que quase deixou o link sair em http. */
  const req = pedido("http://localhost:3000/api/x", {
    "x-forwarded-host": "admin.ktalogu.com.br",
    "x-forwarded-proto": "http",
  });
  assert.equal(origemPublicaDoAdmin(req), "https://admin.ktalogu.com.br");
});

test("endereco de rede interna com porta fica como veio", () => {
  const req = pedido("http://192.168.0.10:3002/api/x", {
    host: "192.168.0.10:3002",
    "x-forwarded-proto": "http",
  });
  assert.equal(origemPublicaDoAdmin(req), "http://192.168.0.10:3002");
});

test("na maquina do programador continua http e com a porta", () => {
  const req = pedido("http://localhost:3002/api/x", { host: "localhost:3002" });
  assert.equal(origemPublicaDoAdmin(req), "http://localhost:3002");
});

test("a variavel de ambiente ganha de qualquer cabecalho", () => {
  process.env.NEXT_PUBLIC_ADMIN_BASE_URL = "https://admin.ktalogu.com.br/";
  const req = pedido("http://localhost:3000/api/x", { "x-forwarded-host": "site-do-atacante.com" });
  assert.equal(origemPublicaDoAdmin(req), "https://admin.ktalogu.com.br");
});

test("sem host nenhum, sobra a URL da requisicao", () => {
  const req = pedido("https://admin.ktalogu.com.br/api/x");
  assert.equal(origemPublicaDoAdmin(req), "https://admin.ktalogu.com.br");
});
