"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.createRoot = createRoot;
function _componentId() {
  const data = require("@teambit/component-id");
  _componentId = function () {
    return data;
  };
  return data;
}
function _toolboxPath() {
  const data = require("@teambit/toolbox.path.to-windows-compatible-path");
  _toolboxPath = function () {
    return data;
  };
  return data;
}
function _lodash() {
  const data = require("lodash");
  _lodash = function () {
    return data;
  };
  return data;
}
function _path() {
  const data = require("path");
  _path = function () {
    return data;
  };
  return data;
}
function _ui() {
  const data = require("./ui.aspect");
  _ui = function () {
    return data;
  };
  return data;
}
async function createRoot(aspectDefs, rootExtensionName, rootAspect = _ui().UIAspect.id, runtime = 'ui', config = {}, ignoreVersion, addRuntimes = false, harmonyPackage, shouldRun = false) {
  const rootId = rootExtensionName ? `'${rootExtensionName}'` : '';
  const identifiers = getIdentifiers(aspectDefs, 'Aspect');
  const idSetters = getIdSetters(aspectDefs, 'Aspect', ignoreVersion);
  config['teambit.harmony/bit'] = rootExtensionName;
  // Escaping "'" in case for example in the config you have something like:
  // description: "team's scope"
  const stringifiedConfig = (0, _toolboxPath().toWindowsCompatiblePath)(JSON.stringify(config)).replace(/'/g, "\\'");
  return `
${createHarmonyImports(harmonyPackage)}
${createImports(aspectDefs)}

${generateSlotsFn()}

${addRuntimes ? addSlots(aspectDefs) : ''}
${addRuntimes ? createAddRuntime(aspectDefs, runtime) : ''}

const isBrowser = typeof window !== "undefined";
const windowConfig = isBrowser ? window.harmonyAppConfig: undefined;
const config = JSON.parse('${stringifiedConfig}');
const mergedConfig = { ...config, ...windowConfig };
${idSetters.join('\n')}
export default function render(...props){
  return Harmony.load([${identifiers.join(', ')}], '${runtime}', mergedConfig)
    .then((harmony) => {
      return harmony
      .run()
      .then(() => harmony.get('${rootAspect}'))
      .then((rootExtension) => {
        const ssrSetup = !isBrowser && rootExtension.setupSsr;
        const setup = rootExtension.setup;
        const setupFunc = (ssrSetup || setup || function noop(){}).bind(rootExtension);

        return (
          Promise.resolve(setupFunc())
            .then(() => rootExtension)
        );
      })
      .then((rootExtension) => {
        if (rootExtension.run) return rootExtension.run();
        if (isBrowser) {
          return rootExtension.render(${rootId}, ...props);
        } else {
          return rootExtension.renderSsr(${rootId}, ...props);
        }
      })
      .catch((err) => {
        throw err;
      });
    });
}

if (isBrowser || '${runtime}' === 'main' || ${shouldRun}) render();
`;
}
function createAddRuntime(aspectDefs, runtime) {
  return aspectDefs.map(aspectDef => {
    const aspectId = getIdentifier(aspectDef, 'Aspect', 'aspectFilePath');
    const runtimeId = getIdentifier(aspectDef, 'Runtime', 'runtimePath');
    const setRuntime = `${runtimeId}.runtime = "${runtime}";\n`;
    return `${setRuntime}${aspectId}.addRuntime(${runtimeId});`;
  }).join('\n');
}
function createImports(aspectDefs) {
  const defs = aspectDefs.filter(def => def.runtimePath);
  return `${getImportStatements(aspectDefs, 'aspectFilePath', 'Aspect')}
${getImportStatements(defs, 'runtimePath', 'Runtime')}`;
}
function createHarmonyImports(harmonyPackage = '@teambit/harmony') {
  return `import { Harmony, Slot } from '${harmonyPackage}';`;
}
function generateSlotsFn() {
  return `
function generateSlot(length = 5) {
  return Array.from(Array(length)).map(() => Slot.withType());
}
`;
}
function addSlots(aspectDefs) {
  return aspectDefs.map(aspectDef => {
    const runtimeId = getIdentifier(aspectDef, 'Runtime', 'runtimePath');
    const setSlots = `${runtimeId}.slots = generateSlot(${runtimeId}?.slotCount)`;
    return `if (!${runtimeId}.slots?.length && ${runtimeId}.provider.length >= 3) ${setSlots} `;
  }).join('\n');
}
function getImportStatements(aspectDefs, pathProp, suffix) {
  return aspectDefs.map(aspectDef => `import ${getIdentifier(aspectDef, suffix, pathProp)} from '${(0, _toolboxPath().toWindowsCompatiblePath)(aspectDef[pathProp])}';`).join('\n');
}
function getIdentifiers(aspectDefs, suffix) {
  return aspectDefs.map(aspectDef => `${getIdentifier(aspectDef, suffix)}`);
}
function getIdSetters(defs, suffix, ignoreVersion) {
  return defs.map(def => {
    if (!def.getId) return undefined;
    const id = _componentId().ComponentID.fromString(def.getId);
    return `${getIdentifier(def, suffix)}.id = '${ignoreVersion ? id.toStringWithoutVersion() : id.toString()}';`;
  }).filter(val => !!val);
}
function getIdentifier(aspectDef, suffix, pathProp) {
  if (!aspectDef.component && !aspectDef.local) {
    return getCoreIdentifier(aspectDef.aspectPath, suffix);
  }
  return getRegularAspectIdentifier(aspectDef, suffix, pathProp);
}
function getRegularAspectIdentifier(aspectDef, suffix, pathProp) {
  const targetName = (0, _lodash().camelCase)(`${(0, _path().parse)(aspectDef.aspectPath).base.replace(/\./, '__').replace('@', '__')}${suffix}`);
  const sourceName = pathProp ? getDefaultOrOnlyExport(aspectDef[pathProp]) : undefined;
  const identifier = sourceName ? `{${sourceName} as ${targetName}}` : targetName;
  return identifier;
}
function getDefaultOrOnlyExport(filePath) {
  try {
    // eslint-disable-next-line import/no-dynamic-require, global-require
    const exports = require(filePath);
    if (exports.default) return undefined;
    if (Object.keys(exports).length === 1) return Object.keys(exports)[0];
  } catch (e) {
    // ignore this error, fallback to just using the default export
  }
  return undefined;
}
function getCoreIdentifier(path, suffix) {
  return (0, _lodash().camelCase)(`${(0, _path().parse)(path).name.split('.')[0]}${suffix}`);
}

//# sourceMappingURL=create-root.js.map