const LOADED = {};

/**
 * @interface LoadType
 * @param {object} type
 * @param {string} type.name
 * @param {string} type.version
 * @param {object} env
 * @returns {Promise<Supernova>}
 */

export async function load(name, version, { config, public: { env } }, loader) {
  const key = `${name}__${version}`;
  if (!LOADED[key]) {
    const sKey = `${name}${(version && ` v${version}`) || ''}`;
    const p = (loader || config.load)(
      {
        name,
        version,
      },
      env
    );
    const prom = Promise.resolve(p);
    LOADED[key] = prom
      .then(sn => {
        if (!sn) {
          // TODO - improve validation
          throw new Error(`load() of supernova '${sKey}' resolved to an invalid object`);
        }
        return sn;
      })
      .catch(e => {
        if (__NEBULA_DEV__) {
          console.warn(e); // eslint-disable-line no-console
        }
        throw new Error(`Failed to load supernova: '${sKey}'`);
      });
  }

  return LOADED[key];
}

export function clearFromCache(name) {
  Object.keys(LOADED).forEach(key => {
    if (key.split('__')[0] === name) {
      LOADED[key] = undefined;
    }
  });
}
