// loaders.gl
// SPDX-License-Identifier: MIT
// Copyright vis.gl contributors
import { parse } from '@loaders.gl/core';
import { I3SContentLoader } from "./i3s-content-loader.js";
import { normalizeTileData, normalizeTilesetData } from "./lib/parsers/parse-i3s.js";
import { COORDINATE_SYSTEM } from "./lib/parsers/constants.js";
import { getUrlWithoutParams } from "./lib/utils/url-utils.js";
// __VERSION__ is injected by babel-plugin-version-inline
// @ts-ignore TS2304: Cannot find name '__VERSION__'.
const VERSION = typeof "4.4.2" !== 'undefined' ? "4.4.2" : 'latest';
const TILESET_REGEX = /layers\/[0-9]+$/;
const LOCAL_SLPK_REGEX = /\.slpk$/;
const TILE_HEADER_REGEX = /nodes\/([0-9-]+|root)$/;
const SLPK_HEX = '504b0304';
const POINT_CLOUD = 'PointCloud';
/**
 * Loader for I3S - Indexed 3D Scene Layer
 */
export const I3SLoader = {
    dataType: null,
    batchType: null,
    name: 'I3S (Indexed Scene Layers)',
    id: 'i3s',
    module: 'i3s',
    version: VERSION,
    mimeTypes: ['application/octet-stream'],
    parse: parseI3S,
    extensions: ['bin'],
    options: {
        i3s: {
            token: undefined,
            isTileset: 'auto',
            isTileHeader: 'auto',
            tile: undefined,
            tileset: undefined,
            _tileOptions: undefined,
            _tilesetOptions: undefined,
            useDracoGeometry: true,
            useCompressedTextures: true,
            decodeTextures: true,
            coordinateSystem: COORDINATE_SYSTEM.METER_OFFSETS
        }
    }
};
async function parseI3S(data, options = {}, context) {
    const url = context.url;
    options.i3s = options.i3s || {};
    const magicNumber = getMagicNumber(data);
    // check if file is slpk
    if (magicNumber === SLPK_HEX) {
        throw new Error('Files with .slpk extention currently are not supported by I3SLoader');
    }
    const urlWithoutParams = getUrlWithoutParams(url);
    // auto detect file type based on url
    let isTileset;
    if (options.i3s.isTileset === 'auto') {
        isTileset = TILESET_REGEX.test(urlWithoutParams) || LOCAL_SLPK_REGEX.test(urlWithoutParams);
    }
    else {
        isTileset = options.i3s.isTileset;
    }
    let isTileHeader;
    if (options.i3s.isTileHeader === 'auto') {
        isTileHeader = TILE_HEADER_REGEX.test(urlWithoutParams);
    }
    else {
        isTileHeader = options.i3s.isTileHeader;
    }
    if (isTileset) {
        data = await parseTileset(data, options, context);
    }
    else if (isTileHeader) {
        data = await parseTile(data, context);
    }
    else {
        data = await parseTileContent(data, options);
    }
    return data;
}
async function parseTileContent(arrayBuffer, options) {
    return await parse(arrayBuffer, I3SContentLoader, options);
}
async function parseTileset(data, options, context) {
    const tilesetJson = JSON.parse(new TextDecoder().decode(data));
    if (tilesetJson?.layerType === POINT_CLOUD) {
        throw new Error('Point Cloud layers currently are not supported by I3SLoader');
    }
    const tilesetPostprocessed = await normalizeTilesetData(tilesetJson, options, context);
    return tilesetPostprocessed;
}
async function parseTile(data, context) {
    data = JSON.parse(new TextDecoder().decode(data));
    return normalizeTileData(data, context);
}
function getMagicNumber(data) {
    if (data instanceof ArrayBuffer) {
        // slice binary data (4 bytes from the beginning) and transform it to hexadecimal numeral system
        return [...new Uint8Array(data, 0, 4)]
            .map((value) => value.toString(16).padStart(2, '0'))
            .join('');
    }
    return null;
}
//# sourceMappingURL=i3s-loader.js.map