/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

/**
 * IFC loading configuration constants and utilities
 * Extracted from useIfc.ts for reusability
 */

import type { DynamicBatchConfig } from '@ifc-lite/geometry';

// ============================================================================
// Server Configuration
// ============================================================================

/** IFC server URL - set via environment variable for server-side IFC processing */
export const SERVER_URL = import.meta.env.VITE_IFC_SERVER_URL || import.meta.env.VITE_SERVER_URL || '';

/**
 * Enable server-side IFC parsing (disabled by default — uses client-side WASM).
 *
 * The server URL may be present for other features (e.g. superset integration)
 * without intending to route normal IFC loading through it.
 *
 * To enable server-side IFC processing for development:
 *   1. Set VITE_IFC_SERVER_URL (or VITE_SERVER_URL) to the server endpoint
 *   2. Set VITE_USE_SERVER=true
 *
 * Example .env:
 *   VITE_IFC_SERVER_URL=https://ifc-server.example.com
 *   VITE_USE_SERVER=true
 */
export const USE_SERVER = SERVER_URL !== '' && import.meta.env.VITE_USE_SERVER === 'true';

// ============================================================================
// File Size Thresholds (in bytes unless noted)
// ============================================================================

/** Minimum file size to cache (10MB) - smaller files parse quickly anyway */
export const CACHE_SIZE_THRESHOLD = 10 * 1024 * 1024;

/** Maximum file size eligible for caching (150MB).
 *  Files above this are not cached at all because the source buffer is required
 *  for on-demand property/quantity extraction, spatial hierarchy elevations,
 *  and IFC re-export.  Caching without it would silently degrade those features,
 *  and including it would make the IndexedDB write prohibitively large. */
export const CACHE_MAX_SOURCE_SIZE = 150 * 1024 * 1024;

/**
 * File size at which the browser-File-API entry path streams directly into a
 * `SharedArrayBuffer` instead of going through `await file.arrayBuffer()`.
 *
 * Below this threshold, the doubled peak (ArrayBuffer + SAB) is small enough
 * that the simpler one-shot read is preferable. Above it, the streaming path
 * shaves ~`fileSize` MB from peak memory and avoids hitting V8's per-buffer
 * allocation limits on huge files. (Issue #600.)
 */
export const STREAM_SAB_THRESHOLD = 256 * 1024 * 1024;

/**
 * File size at which the browser parser worker defers indexing of property
 * atoms (`IFCPROPERTYSINGLEVALUE`, `IFCPROPERTYENUMERATEDVALUE`, etc.) until
 * a property panel actually opens.
 *
 * On a 14 M-entity, 986 MB file roughly 3.4 M of those entities are
 * property atoms. Skipping them in the primary `compactByIdIndex` shaves
 * ~4 s off the parse path; the deferred index is built on-demand in
 * ~50 ms when the first property panel hydrates. Mirrors the desktop
 * `hugeNativeMode` gate.
 */
export const HUGE_BROWSER_FILE_THRESHOLD = 500 * 1024 * 1024;

/** File size thresholds for various optimizations */
export const THRESHOLDS = {
  /** Use streaming Parquet above this (150MB) */
  STREAMING_MB: 150,
  /** Use Parquet vs JSON above this (10MB) */
  PARQUET_MB: 10,
  /** Large file threshold affecting batch sizing (50MB) */
  LARGE_FILE_MB: 50,
  /** Huge file threshold for aggressive batching (100MB) */
  HUGE_FILE_MB: 100,
  /** Don't cache files smaller than this (10MB) */
  CACHE_MIN_MB: 10,
} as const;

// ============================================================================
// Dynamic Batch Configuration
// ============================================================================

/**
 * Calculate dynamic batch config based on file size
 * Larger files get larger batches for better throughput
 *
 * @param fileSizeMB - File size in megabytes
 * @returns Batch configuration for geometry processing
 */
export function getDynamicBatchConfig(fileSizeMB: number): DynamicBatchConfig {
  if (fileSizeMB < 10) {
    // Small files: smaller batches for responsiveness
    return { initialBatchSize: 50, maxBatchSize: 200, fileSizeMB };
  } else if (fileSizeMB < 50) {
    // Medium files: balanced batching
    return { initialBatchSize: 100, maxBatchSize: 500, fileSizeMB };
  } else if (fileSizeMB < 100) {
    // Large files: larger batches for throughput
    return { initialBatchSize: 100, maxBatchSize: 1000, fileSizeMB };
  } else {
    // Huge files (100MB+): aggressive batching for maximum throughput
    return { initialBatchSize: 100, maxBatchSize: 3000, fileSizeMB };
  }
}

/**
 * Convert bytes to megabytes
 */
export function bytesToMB(bytes: number): number {
  return bytes / (1024 * 1024);
}
