"use strict";

import { base64ToTypedArray, typedArrayToBase64 } from "../../utils/tensorUtils.js";

// Minimal onnxruntime-web types (detected at runtime via window.ort)

export function OnnxInferenceMixin(Base) {
  return class extends Base {
    /** @internal */_onnxSessions = new Map();
    /** @internal */
    _onnxNextId = 0;
    async createOnnxSession(config) {
      if (!window.ort) {
        return {
          success: false,
          sessionId: '',
          inputNames: [],
          outputNames: [],
          error: 'onnxruntime-web not loaded. Add <script src="ort.min.js"> to your page.'
        };
      }
      try {
        const options = config.numThreads ? {
          intraOpNumThreads: config.numThreads
        } : undefined;
        const session = await window.ort.InferenceSession.create(config.modelPath, options);
        this._onnxNextId++;
        const sessionId = `web_onnx_${this._onnxNextId}`;
        this._onnxSessions.set(sessionId, session);
        return {
          success: true,
          sessionId,
          inputNames: [...session.inputNames],
          outputNames: [...session.outputNames]
        };
      } catch (e) {
        return {
          success: false,
          sessionId: '',
          inputNames: [],
          outputNames: [],
          error: e instanceof Error ? e.message : String(e)
        };
      }
    }
    async runOnnxSession(sessionId, inputs) {
      if (!window.ort) {
        return {
          success: false,
          error: 'onnxruntime-web not loaded.'
        };
      }
      const session = this._onnxSessions.get(sessionId);
      if (!session) {
        return {
          success: false,
          error: `Session not found: ${sessionId}`
        };
      }
      try {
        // Convert OnnxTensorData to ort.Tensor
        const feeds = {};
        for (const [name, td] of Object.entries(inputs)) {
          const typedData = base64ToTypedArray(td.data, td.type);
          feeds[name] = new window.ort.Tensor(td.type, typedData, td.dims);
        }
        const results = await session.run(feeds);

        // Convert ort.Tensor outputs to OnnxTensorData
        const outputs = {};
        for (const [name, tensor] of Object.entries(results)) {
          outputs[name] = {
            type: tensor.type,
            dims: [...tensor.dims],
            data: typedArrayToBase64(tensor.data)
          };
        }
        return {
          success: true,
          outputs
        };
      } catch (e) {
        return {
          success: false,
          error: e instanceof Error ? e.message : String(e)
        };
      }
    }
    async releaseOnnxSession(sessionId) {
      const session = this._onnxSessions.get(sessionId);
      if (!session) {
        return {
          released: false
        };
      }
      try {
        await session.release();
      } catch {
        // Ignore release errors
      }
      this._onnxSessions.delete(sessionId);
      return {
        released: true
      };
    }
  };
}
//# sourceMappingURL=onnxInference.js.map