'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

require('babel-polyfill');

var _circularJson = require('circular-json');

var _circularJson2 = _interopRequireDefault(_circularJson);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _fsExtra = require('fs-extra');

var _fsExtra2 = _interopRequireDefault(_fsExtra);

var _log = require('@reactant/core/log');

var _log2 = _interopRequireDefault(_log);

var _path = require('path');

var _path2 = _interopRequireDefault(_path);

var _pkgDir = require('pkg-dir');

var _pkgDir2 = _interopRequireDefault(_pkgDir);

var _webpack = require('@reactant/cli/webpack');

var _config = require('@reactant/cli/config');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function getMergeConfiguration() {
  let mergeConfiguration = null;
  try {
    mergeConfiguration = require('merge-configuration').default;
  } catch (err) {
    mergeConfiguration = require('@reactant/web-isomorphic/node_modules/merge-configuration').default;
  }
  return mergeConfiguration;
}

const mergeConfiguration = getMergeConfiguration();
let debug = false;
if (_lodash2.default.includes(process.argv, '--verbose')) (0, _log.setLevel)('verbose');
if (_lodash2.default.includes(process.argv, '--debug')) {
  (0, _log.setLevel)('debug');
  debug = true;
}

module.exports = webpackConfig => {
  const config = (0, _config.rebuildConfig)({ options: { platform: 'web', debug } });
  const paths = config.paths,
        babel = config.babel,
        options = config.options;

  webpackConfig = (0, _webpack.createWebpackConfig)(config, webpackConfig);
  webpackConfig.resolve.extensions.unshift('.web.js');
  webpackConfig.externals = _extends({}, webpackConfig.externals, {
    child_process: {},
    deasync: {},
    fs: {},
    winston: {}
  });
  webpackConfig = replaceBabelRule(webpackConfig, {
    test: /\.(js|jsx|mjs)$/,
    include: [paths.src, paths.stories, ...getModuleIncludes(['react-navigation', 'static-container'], config)],
    loader: require.resolve('babel-loader'),
    options: babel
  });
  webpackConfig = mergeConfiguration(webpackConfig, config.storybook, {}, config);
  if (options.debug) {
    _fsExtra2.default.mkdirsSync(paths.debug);
    _fsExtra2.default.writeFileSync(_path2.default.resolve(paths.debug, 'webpack.storybook.json'), _circularJson2.default.stringify(webpackConfig, null, 2));
  }
  _log2.default.debug('webpackConfig', webpackConfig);
  return webpackConfig;
};

function getModuleIncludes(modules, config) {
  const paths = config.paths;

  const includes = [];
  modules.forEach(module => {
    try {
      const modulePath = _pkgDir2.default.sync(require.resolve(_path2.default.resolve(paths.root, 'node_modules', module)));
      includes.push(modulePath);
    } catch (err) {}
  });
  return includes;
}

function replaceBabelRule(webpackConfig, rule) {
  const babelRule = _lodash2.default.find(webpackConfig.module.rules, rule => {
    return !!_lodash2.default.find(_lodash2.default.isArray(rule.use) ? rule.use : [], rule => rule.loader.indexOf('babel-loader') > -1);
  });
  _lodash2.default.each(_lodash2.default.keys(babelRule), key => {
    delete babelRule[key];
  });
  _lodash2.default.assign(babelRule, rule);
  return webpackConfig;
}