import assert from "node:assert/strict";
import { test } from "node:test";
import { lerErro, lerIdDoEnvio, lerPartes, montarConclusao } from "./respostas-s3.ts";

test("lê o id do envio em partes", () => {
  const xml = `<?xml version="1.0" encoding="UTF-8"?><InitiateMultipartUploadResult><Bucket>ktalogu-digitais</Bucket><Key>a/b</Key><UploadId>AAAA-bbb_cc~1</UploadId></InitiateMultipartUploadResult>`;
  assert.equal(lerIdDoEnvio(xml), "AAAA-bbb_cc~1");
  assert.equal(lerIdDoEnvio("<x/>"), null);
  assert.equal(lerIdDoEnvio("<UploadId></UploadId>"), null);
});

test("lê as partes com ETag entre aspas codificadas", () => {
  const xml = `<ListPartsResult><IsTruncated>true</IsTruncated><NextPartNumberMarker>2</NextPartNumberMarker>
    <Part><PartNumber>2</PartNumber><ETag>&quot;bbb&quot;</ETag><Size>10</Size></Part>
    <Part><PartNumber>1</PartNumber><ETag>"aaa"</ETag><Size>16777216</Size></Part>
    <Part><PartNumber>x</PartNumber><ETag>"zzz"</ETag></Part>
  </ListPartsResult>`;
  const lido = lerPartes(xml);
  assert.deepEqual(lido.partes, [
    { numero: 2, etag: '"bbb"', tamanho: 10 },
    { numero: 1, etag: '"aaa"', tamanho: 16777216 },
  ]);
  assert.equal(lido.truncado, true);
  assert.equal(lido.proximo, 2);
});

test("monta a conclusão com as partes em ordem e XML escapado", () => {
  assert.equal(
    montarConclusao([{ numero: 2, etag: '"b&"' }, { numero: 1, etag: '"a"' }]),
    '<CompleteMultipartUpload><Part><PartNumber>1</PartNumber><ETag>"a"</ETag></Part><Part><PartNumber>2</PartNumber><ETag>"b&amp;"</ETag></Part></CompleteMultipartUpload>',
  );
});

test("lê o erro do S3", () => {
  assert.deepEqual(lerErro("<Error><Code>NoSuchUpload</Code><Message>The upload does not exist</Message></Error>"), {
    codigo: "NoSuchUpload",
    mensagem: "The upload does not exist",
  });
  assert.equal(lerErro(""), null);
});

test("resposta enorme ou sem fim não trava", () => {
  const enorme = "<Part>".repeat(400000);
  const inicio = Date.now();
  assert.deepEqual(lerPartes(enorme).partes, []);
  assert.equal(lerIdDoEnvio("<UploadId>" + "a".repeat(3 * 1024 * 1024)), null);
  assert.ok(Date.now() - inicio < 1000);
});
