"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.createReactAppConfig = createReactAppConfig;
var _path = _interopRequireDefault(require("path"));
var _invariant = _interopRequireDefault(require("invariant"));
var _utils = require("@webiny/cli-plugin-deploy-pulumi/utils");
var _projectUtils = require("@webiny/project-utils");
const NO_ENV_MESSAGE = `Please specify the environment via the "--env" argument, for example: "--env dev".`;
const NO_API_MESSAGE = env => {
  return `It seems that the API project application isn't deployed!\nBefore continuing, please deploy it by running the following command: yarn webiny deploy apps/api --env=${env}`;
};
function createEnvModifierFromMap(app, map, options) {
  return ({
    env
  }) => {
    const output = (0, _utils.getStackOutput)({
      folder: app,
      env: options.env,
      variant: options.variant,
      map
    });
    (0, _invariant.default)(output, NO_API_MESSAGE(options.env));
    return {
      ...env,
      ...output
    };
  };
}
function createEmptyReactConfig(options) {
  const webpackModifiers = [];
  const babelModifiers = [];
  const commandsModifiers = [];
  const customEnvModifiers = [];
  const pulumiOutputToEnvModifiers = [];
  const entryModifiers = [];
  const loadEnvVars = () => {
    const outputCache = new Map();
    let envVars = pulumiOutputToEnvModifiers.reduce((env, [app, modifier]) => {
      if (!outputCache.has(app)) {
        outputCache.set(app, (0, _utils.getStackOutput)({
          folder: app,
          env: options.env,
          variant: options.variant
        }));
      }
      return modifier({
        output: outputCache.get(app),
        env
      });
    }, {});
    envVars = customEnvModifiers.reduce((env, modifier) => modifier(env), envVars);
    Object.assign(process.env, envVars);
  };
  const createOverrides = () => {
    const defaultEntry = _path.default.join(options.cwd, "src", "index.tsx");
    return {
      entry: entryModifiers.reduce((entry, modifier) => modifier(entry), defaultEntry),
      webpack(config) {
        return webpackModifiers.reduce((config, modifier) => modifier(config), config);
      },
      babel(config) {
        return babelModifiers.reduce((config, modifier) => modifier(config), config);
      }
    };
  };
  const commands = {
    build() {
      (0, _invariant.default)(options.env, NO_ENV_MESSAGE);
      loadEnvVars();
      return (0, _projectUtils.createBuildApp)({
        cwd: process.cwd(),
        overrides: createOverrides()
      })(options);
    },
    watch() {
      (0, _invariant.default)(options.env, NO_ENV_MESSAGE);
      loadEnvVars();
      return (0, _projectUtils.createWatchApp)({
        cwd: process.cwd(),
        overrides: createOverrides()
      })(options);
    }
  };
  return {
    commands(modifier) {
      commandsModifiers.push(modifier);
    },
    babel(modifier) {
      babelModifiers.push(modifier);
    },
    webpack(modifier) {
      webpackModifiers.push(modifier);
    },
    customEnv(modifier) {
      customEnvModifiers.push(modifier);
    },
    pulumiOutputToEnv(app, modifier) {
      if (typeof modifier === "function") {
        pulumiOutputToEnvModifiers.push([app, modifier]);
        return;
      }
      pulumiOutputToEnvModifiers.push([app, createEnvModifierFromMap(app, modifier, options)]);
    },
    entry(modifier) {
      entryModifiers.push(modifier);
    },
    seal() {
      return {
        commands: commandsModifiers.reduce((commands, modifier) => modifier(commands), commands)
      };
    }
  };
}
function createReactAppConfig(customizer) {
  return ({
    options
  }) => {
    const config = createEmptyReactConfig(options);
    if (typeof customizer === "function") {
      customizer({
        options,
        config
      });
    }

    // Generate config object to be returned to the CLI
    return config.seal();
  };
}

//# sourceMappingURL=createReactAppConfig.js.map