"use strict";

// Import the native module and potentially substitute with web implementation
import { Platform } from 'react-native';
import NativeModuleImport from "./NativeSherpaOnnxSpec.js";
import { WebSherpaOnnxImpl } from "./WebSherpaOnnxImpl.js";

// On web, WebSherpaOnnxImpl already implements ApiInterface directly (object params).
// On native, NativeModuleImport uses positional args — SherpaOnnxAPI adapts them below.
const webImpl =
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Platform.OS === 'web' ? new WebSherpaOnnxImpl() : null;

// NativeSherpaOnnx is only used on native (positional-arg TurboModule interface).
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const NativeSherpaOnnx = NativeModuleImport;

// Log a warning if the native module is missing on a native platform
if (!NativeModuleImport && Platform.OS !== 'web') {
  console.warn('SherpaOnnx native module not available on this platform');
}

/**
 * Implementation of the SherpaOnnx API
 * On web: delegates directly to WebSherpaOnnxImpl (which already implements ApiInterface).
 * On native: adapts positional-arg TurboModule calls to the object-param ApiInterface.
 */
const nativeAdapter = {
  testOnnxIntegration() {
    return NativeSherpaOnnx.testOnnxIntegration();
  },
  validateLibraryLoaded() {
    return NativeSherpaOnnx.validateLibraryLoaded();
  },
  getArchitectureInfo() {
    return NativeSherpaOnnx.getArchitectureInfo();
  },
  getSystemInfo() {
    return NativeSherpaOnnx.getSystemInfo();
  },
  /**
   * Initialize the TTS engine with the provided model configuration
   * @param config Configuration for the TTS model
   * @returns Promise that resolves with initialization result
   */
  initTts(config) {
    return NativeSherpaOnnx.initTts(config);
  },
  generateTts(config) {
    return NativeSherpaOnnx.generateTts(config);
  },
  stopTts() {
    return NativeSherpaOnnx.stopTts();
  },
  releaseTts() {
    return NativeSherpaOnnx.releaseTts();
  },
  // ASR methods
  initAsr(config) {
    // Flatten modelFiles into top-level keys for TurboModule compatibility
    const nativeConfig = {
      modelDir: config.modelDir,
      modelType: config.modelType,
      numThreads: config.numThreads,
      debug: config.debug,
      streaming: config.streaming,
      decodingMethod: config.decodingMethod,
      maxActivePaths: config.maxActivePaths,
      provider: config.provider,
      language: config.language,
      task: config.task,
      useItn: config.useItn,
      srcLang: config.srcLang,
      tgtLang: config.tgtLang,
      usePnc: config.usePnc,
      usePunct: config.usePunct,
      hotwords: config.hotwords
    };
    if (config.modelFiles) {
      nativeConfig.modelFileEncoder = config.modelFiles.encoder;
      nativeConfig.modelFileDecoder = config.modelFiles.decoder;
      nativeConfig.modelFileJoiner = config.modelFiles.joiner;
      nativeConfig.modelFileTokens = config.modelFiles.tokens;
      nativeConfig.modelFileModel = config.modelFiles.model;
      nativeConfig.modelFilePreprocessor = config.modelFiles.preprocessor;
      nativeConfig.modelFileUncachedDecoder = config.modelFiles.uncachedDecoder;
      nativeConfig.modelFileCachedDecoder = config.modelFiles.cachedDecoder;
      nativeConfig.modelFileConvFrontend = config.modelFiles.convFrontend;
      nativeConfig.modelFileTokenizer = config.modelFiles.tokenizer;
    }
    if (config.qwen3) {
      nativeConfig.qwen3MaxTotalLen = config.qwen3.maxTotalLen;
      nativeConfig.qwen3MaxNewTokens = config.qwen3.maxNewTokens;
      nativeConfig.qwen3Temperature = config.qwen3.temperature;
      nativeConfig.qwen3TopP = config.qwen3.topP;
      nativeConfig.qwen3Seed = config.qwen3.seed;
    }
    return NativeSherpaOnnx.initAsr(nativeConfig);
  },
  recognizeFromSamples({
    sampleRate,
    samples
  }) {
    return NativeSherpaOnnx.recognizeFromSamples(sampleRate, samples);
  },
  recognizeFromFile(filePath) {
    return NativeSherpaOnnx.recognizeFromFile(filePath);
  },
  releaseAsr() {
    return NativeSherpaOnnx.releaseAsr();
  },
  // ASR online streaming primitives
  createAsrOnlineStream() {
    return NativeSherpaOnnx.createAsrOnlineStream();
  },
  acceptAsrOnlineWaveform({
    sampleRate,
    samples
  }) {
    return NativeSherpaOnnx.acceptAsrOnlineWaveform(sampleRate, samples);
  },
  isAsrOnlineEndpoint() {
    return NativeSherpaOnnx.isAsrOnlineEndpoint();
  },
  getAsrOnlineResult() {
    return NativeSherpaOnnx.getAsrOnlineResult();
  },
  finishAsrOnlineInput() {
    return NativeSherpaOnnx.finishAsrOnlineInput();
  },
  resetAsrOnlineStream() {
    return NativeSherpaOnnx.resetAsrOnlineStream();
  },
  // Audio tagging methods
  initAudioTagging(config) {
    return NativeSherpaOnnx.initAudioTagging(config);
  },
  processAndComputeAudioTagging({
    filePath
  }) {
    return NativeSherpaOnnx.processAndComputeAudioTagging(filePath);
  },
  processAndComputeAudioSamples({
    sampleRate,
    samples
  }) {
    return NativeSherpaOnnx.processAndComputeAudioSamples(sampleRate, samples);
  },
  releaseAudioTagging() {
    return NativeSherpaOnnx.releaseAudioTagging();
  },
  // Speaker ID methods
  initSpeakerId(config) {
    return NativeSherpaOnnx.initSpeakerId(config);
  },
  processSpeakerIdSamples({
    sampleRate,
    samples
  }) {
    return NativeSherpaOnnx.processSpeakerIdSamples(sampleRate, samples);
  },
  computeSpeakerEmbedding() {
    return NativeSherpaOnnx.computeSpeakerEmbedding();
  },
  resetSpeakerIdStream() {
    return NativeSherpaOnnx.resetSpeakerIdStream();
  },
  registerSpeaker({
    name,
    embedding
  }) {
    return NativeSherpaOnnx.registerSpeaker(name, embedding);
  },
  removeSpeaker(name) {
    return NativeSherpaOnnx.removeSpeaker(name);
  },
  getSpeakers() {
    return NativeSherpaOnnx.getSpeakers();
  },
  identifySpeaker({
    embedding,
    threshold
  }) {
    return NativeSherpaOnnx.identifySpeaker(embedding, threshold);
  },
  verifySpeaker({
    name,
    embedding,
    threshold
  }) {
    return NativeSherpaOnnx.verifySpeaker(name, embedding, threshold);
  },
  processSpeakerIdFile(filePath) {
    return NativeSherpaOnnx.processSpeakerIdFile(filePath);
  },
  processSpeakerIdFileWindow({
    filePath,
    startTimeMs,
    durationMs
  }) {
    return NativeSherpaOnnx.processSpeakerIdFileWindow(filePath, startTimeMs, durationMs);
  },
  releaseSpeakerId() {
    return NativeSherpaOnnx.releaseSpeakerId();
  },
  // Diarization methods
  initDiarization(config) {
    return NativeSherpaOnnx.initDiarization(config);
  },
  processDiarizationFile({
    filePath,
    numClusters,
    threshold
  }) {
    return NativeSherpaOnnx.processDiarizationFile(filePath, numClusters, threshold);
  },
  processDiarizationFileWindow({
    filePath,
    startTimeMs,
    durationMs,
    numClusters,
    threshold
  }) {
    return NativeSherpaOnnx.processDiarizationFileWindow(filePath, startTimeMs, durationMs, numClusters, threshold);
  },
  releaseDiarization() {
    return NativeSherpaOnnx.releaseDiarization();
  },
  // KWS methods
  initKws(config) {
    return NativeSherpaOnnx.initKws(config);
  },
  acceptKwsWaveform({
    sampleRate,
    samples
  }) {
    return NativeSherpaOnnx.acceptKwsWaveform(sampleRate, samples);
  },
  resetKwsStream() {
    return NativeSherpaOnnx.resetKwsStream();
  },
  releaseKws() {
    return NativeSherpaOnnx.releaseKws();
  },
  // VAD methods
  initVad(config) {
    return NativeSherpaOnnx.initVad(config);
  },
  acceptVadWaveform({
    sampleRate,
    samples
  }) {
    return NativeSherpaOnnx.acceptVadWaveform(sampleRate, samples);
  },
  resetVad() {
    return NativeSherpaOnnx.resetVad();
  },
  releaseVad() {
    return NativeSherpaOnnx.releaseVad();
  },
  // Language ID methods
  initLanguageId(config) {
    return NativeSherpaOnnx.initLanguageId(config);
  },
  detectLanguage({
    sampleRate,
    samples
  }) {
    return NativeSherpaOnnx.detectLanguage(sampleRate, samples);
  },
  detectLanguageFromFile(filePath) {
    return NativeSherpaOnnx.detectLanguageFromFile(filePath);
  },
  releaseLanguageId() {
    return NativeSherpaOnnx.releaseLanguageId();
  },
  // Punctuation methods
  initPunctuation(config) {
    return NativeSherpaOnnx.initPunctuation(config);
  },
  addPunctuation(text) {
    return NativeSherpaOnnx.addPunctuation(text);
  },
  releasePunctuation() {
    return NativeSherpaOnnx.releasePunctuation();
  },
  // Denoising methods
  initDenoiser(config) {
    return NativeSherpaOnnx.initDenoiser(config);
  },
  denoiseFile(filePath) {
    return NativeSherpaOnnx.denoiseFile(filePath);
  },
  releaseDenoiser() {
    return NativeSherpaOnnx.releaseDenoiser();
  },
  // ONNX Inference methods
  createOnnxSession(config) {
    return NativeSherpaOnnx.createOnnxSession(config);
  },
  runOnnxSession(sessionId, inputs) {
    // Convert Record<string, OnnxTensorData> to parallel arrays for the native bridge
    const entries = Object.entries(inputs);
    const inputNames = entries.map(([name]) => name);
    const inputTypes = entries.map(([, t]) => t.type);
    const inputDims = entries.map(([, t]) => t.dims.join(','));
    const inputData = entries.map(([, t]) => t.data);
    return NativeSherpaOnnx.runOnnxSession(sessionId, inputNames, inputTypes, inputDims, inputData).then(result => {
      if (!result.success || !result.outputNames) {
        return {
          success: result.success,
          error: result.error
        };
      }
      // Reconstruct Record<string, OnnxTensorData> from parallel arrays
      const outputs = {};
      for (let i = 0; i < result.outputNames.length; i++) {
        const name = result.outputNames[i];
        outputs[name] = {
          type: result.outputTypes?.[i] ?? 'float32',
          dims: (result.outputDims?.[i] ?? '').split(',').map(Number),
          data: result.outputData?.[i] ?? ''
        };
      }
      return {
        success: true,
        outputs
      };
    });
  },
  releaseOnnxSession(sessionId) {
    return NativeSherpaOnnx.releaseOnnxSession(sessionId);
  },
  // Archive methods
  extractTarBz2({
    sourcePath,
    targetDir
  }) {
    return NativeSherpaOnnx.extractTarBz2(sourcePath, targetDir).then(result => ({
      ...result,
      extractedFiles: result.extractedFiles || []
    }));
  }
};

// On web use WebSherpaOnnxImpl directly (already implements ApiInterface with object params).
// On native use the adapter that converts object params → positional TurboModule args.
export const SherpaOnnxAPI = webImpl ?? nativeAdapter;
//# sourceMappingURL=SherpaOnnxAPI.js.map