// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// The initialize() function exported here is called by module entrypoint scripts
// for each supported target framework version, generated by pack.js:
//  - index.js
//  - net472.js
//  - net8.0.js
//  - ...
module.exports = initialize;

const ridPlatform =
  process.platform === 'win32' ? 'win' :
  process.platform === 'darwin' ? 'osx' :
  process.platform;
const ridArch = process.arch === 'ia32' ? 'x86' : process.arch;
const rid = `${ridPlatform}-${ridArch}`;

const defaultTargetFramework = 'net8.0';

/**
 * The loaded instance of the .NET Runtime. Only one instance/version may be loaded in the process.
 */
let dotnet = undefined;

/**
 * Initializes the Node API .NET host.
 * @param {string?} targetFramework Minimum requested .NET version. Must be one of the target
 * framework monikers supported by the Node API .NET package. The actual loaded version of .NET
 * may be higher, if the requested version is not installed.
 * @returns {import('./index')} The Node API .NET host.
 */
function initialize(targetFramework) {
  if (!targetFramework) {
    // Some version was already loaded and no specific version was requested.
    // Return the already-loaded version.
    if (dotnet) {
      return dotnet;
    }

    targetFramework = defaultTargetFramework;
  }

  /**
   * Build tools like webpack are not able to package up dynamic includes like the default case.
   * The switch supports the currently packaged DLLs to work with build tools while maintaining 
   * potential backwards and future compatibility utilizing the default case. 
   */
  const assemblyName = 'Microsoft.JavaScript.NodeApi';
  let nativeHost;
  switch(rid) {
    case 'win-x64':
      nativeHost = require(`./win-x64/${assemblyName}.node`);
      break;
    case 'win-arm64':
      nativeHost = require(`./win-arm64/${assemblyName}.node`);
      break;
    case 'osx-x64':
      nativeHost = require(`./osx-x64/${assemblyName}.node`);
      break;
    case 'osx-arm64':
      nativeHost = require(`./osx-arm64/${assemblyName}.node`);
      break;
    case 'linux-x64':
      nativeHost = require(`./linux-x64/${assemblyName}.node`);
      break;
    default:
      // Handle unknown platform (Likely will not work with build tools e.g. webpack)
      nativeHost = require(__dirname + `/${rid}/${assemblyName}.node`);
  }

  const managedHostPath = __dirname + `/${targetFramework}/${assemblyName}.DotNetHost.dll`

  // Pass require() and import() functions to the host initialize() method.
  // Since `import` is a keyword and not a function it has to be wrapped in a function value.
  const importModule = function importModule(modulePath) { return import(modulePath); };

  dotnet = nativeHost.initialize(targetFramework, managedHostPath, require, importModule);
  return dotnet;
}
