import { access } from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { createGameAssetIO, convertDocumentTexturesToKtx2 } from "./lib/ktx2.mjs";

const repositoryRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const sourceRoot = path.join(repositoryRoot, "game_assets");
const sourceAssets = [
  "models/claudecraft/chars/players/druid.glb",
  "models/claudecraft/chars/players/knight.glb",
  "models/claudecraft/chars/players/mage.glb",
  "models/claudecraft/chars/players/ranger.glb",
  "models/claudecraft/chars/players/rogue.glb",
  "models/claudecraft/weapons/adv_dagger.glb",
  "models/claudecraft/weapons/adv_druid_staff.glb",
  "models/claudecraft/weapons/adv_sword_1handed.glb",
  "models/claudecraft/weapons/adv_wand.glb",
  "models/claudecraft/weapons/crossbow_2handed.glb",
  "models/claudecraft/weapons/shield_badge.glb",
  "models/claudecraft/weapons/spellbook_open.glb",
];

function optimizedPath(sourcePath) {
  return sourcePath.replace(/\.glb$/, "-uastc.glb");
}

function sortedNames(properties) {
  return properties.map((property) => property.getName()).sort();
}

const io = await createGameAssetIO();
for (const relativePath of sourceAssets) {
  const inputPath = path.join(sourceRoot, relativePath);
  const outputRelativePath = optimizedPath(relativePath);
  const outputPath = path.join(sourceRoot, outputRelativePath);
  await access(inputPath);

  const document = await io.read(inputPath);
  const sourceRootProperties = document.getRoot();
  const expected = {
    animations: sortedNames(sourceRootProperties.listAnimations()),
    materials: sortedNames(sourceRootProperties.listMaterials()),
    meshes: sortedNames(sourceRootProperties.listMeshes()),
    nodes: sortedNames(sourceRootProperties.listNodes()),
    scenes: sortedNames(sourceRootProperties.listScenes()),
    textureCount: sourceRootProperties.listTextures().length,
  };

  await convertDocumentTexturesToKtx2(document, "iwt-ktx2-");
  await io.write(outputPath, document);

  const outputDocument = await io.read(outputPath);
  const outputRoot = outputDocument.getRoot();
  const actual = {
    animations: sortedNames(outputRoot.listAnimations()),
    materials: sortedNames(outputRoot.listMaterials()),
    meshes: sortedNames(outputRoot.listMeshes()),
    nodes: sortedNames(outputRoot.listNodes()),
    scenes: sortedNames(outputRoot.listScenes()),
    textureCount: outputRoot.listTextures().length,
  };
  if (
    JSON.stringify(actual) !== JSON.stringify(expected)
    || outputRoot.listTextures().some((texture) => texture.getMimeType() !== "image/ktx2")
    || outputRoot.listExtensionsUsed().some((extension) => extension.extensionName === "EXT_texture_webp")
  ) {
    throw new Error(`Generated asset failed round-trip validation: ${outputRelativePath}`);
  }
  console.log(`Built game_assets/${outputRelativePath}`);
}
