import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import test from "node:test";
import ApproximateTerrainHeights from "@cesium/engine/Source/Core/ApproximateTerrainHeights.js";
import Cartesian3 from "@cesium/engine/Source/Core/Cartesian3.js";
import GroundPolylineGeometry from "@cesium/engine/Source/Core/GroundPolylineGeometry.js";
import { normalizeHGeoZoneRing } from "../apps/catalog/src/hGeoZoneProjection.mjs";

test("normalizes GeoJSON closure and adjacent duplicates without changing the polygon", () => {
  assert.deepEqual(normalizeHGeoZoneRing([
    [37, 55],
    [37, 55],
    [38, 55],
    [38, 56],
    [37, 55],
    [37, 55],
  ]), [
    [37, 55],
    [38, 55],
    [38, 56],
  ]);
});

test("rejects an invalid or degenerate ring instead of publishing partial geometry", () => {
  assert.deepEqual(normalizeHGeoZoneRing([[37, 55], [38, 55], [37, 55]]), []);
  assert.deepEqual(normalizeHGeoZoneRing([[37, 55], [38, Number.NaN], [38, 56], [37, 55]]), []);
  assert.deepEqual(normalizeHGeoZoneRing([[37, 55], [181, 55], [38, 56], [37, 55]]), []);
});

test("normalized double-closed ring is accepted by Cesium GroundPolylineGeometry", async () => {
  ApproximateTerrainHeights._terrainHeights = JSON.parse(await readFile(
    new URL("../node_modules/@cesium/engine/Source/Assets/approximateTerrainHeights.json", import.meta.url),
    "utf8",
  ));
  const positions = normalizeHGeoZoneRing([
    [37.55, 55.75],
    [37.56, 55.75],
    [37.56, 55.76],
    [37.55, 55.75],
    [37.55, 55.75],
  ]).map(([longitude, latitude]) => Cartesian3.fromDegrees(longitude, latitude));
  const geometry = GroundPolylineGeometry.createGeometry(new GroundPolylineGeometry({
    positions,
    width: 1.5,
    loop: true,
  }));
  assert.ok(geometry);
});
