const fs = require('fs')
const path = require('path')
const webpack = require('webpack')

const { CheckerPlugin } = require('awesome-typescript-loader')
const ProgressBarPlugin = require('progress-bar-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')

let aliasMap = {
  locales: path.join(__dirname, 'fe', 'locales'),
  lib: path.join(__dirname, 'fe', 'lib'),
  js: path.join(__dirname, 'fe', 'js'),
  nextgen: path.join(__dirname, 'fe', 'nextgen'),
  miniprogram: path.join(__dirname, 'miniprogram', 'src'),
  manifests: path.join(__dirname, 'fe', 'manifests'),
  v3vendor: path.join(__dirname, 'vendor', 'assets', 'javascripts'),
  common: path.join(__dirname, 'common'),
  root: path.join(__dirname, 'bower_components'),
}

if (['v4-style', 'editor-debug'].indexOf(process.env.MODE) >= 0) {
  const styleSheetsPath = path.join(__dirname, 'fe', 'styles')
  aliasMap = Object.assign(
    {
      fonts: path.join(__dirname, 'fe', 'fonts'),
      images: path.join(__dirname, 'fe', 'images'),
      fancybox3: path.join(styleSheetsPath, 'fancybox3'),
      strikingly_shared: path.join(styleSheetsPath, 'strikingly_shared'),
      support_widget: path.join(styleSheetsPath, 'support_widget'),
      themes: path.join(styleSheetsPath, 'themes'),
      typefaces: path.join(styleSheetsPath, 'typefaces'),
      v4: path.join(styleSheetsPath, 'v4'),
      ecommerce: path.join(styleSheetsPath, 'ecommerce'),
      portfolio: path.join(styleSheetsPath, 'portfolio'),
      miniprogram: path.join(styleSheetsPath, 'miniprogram'),
    },
    {
      // Is not typical usage of webpack alias. However, it needs this currently,
      // because alots of stylesheets that coming from different layers of folder have to import them
      // 'css-domain-purchase': path.join(styleSheetsPath, 'domain-purchase.less'),
      'css-layers': path.join(styleSheetsPath, 'layers.less'),
      reset: path.join(styleSheetsPath, '_reset.less'),
      // fancybox: path.join(__dirname, 'vendor', 'assets', 'stylesheets', 'fancybox.less'),
      'css-tooltip': path.join(
        __dirname,
        'vendor',
        'assets',
        'stylesheets',
        'tooltip.less'
      ),
      'css-pikaday': path.join(
        __dirname,
        'vendor',
        'assets',
        'stylesheets',
        'pikaday.css'
      ),
    },
    aliasMap
  )
}

let shim = '\n'
shim += 'if (!this._babelPolyfill) {\n'
shim += fs.readFileSync(
  path.join(__dirname, 'node_modules', 'babel-polyfill', 'browser.js')
)
shim += '}\n'

const plugins = [
  new webpack.PrefetchPlugin('react'),
  // new webpack.ResolverPlugin(
  //     new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
  //   ),
  //    new webpack.optimize.DedupePlugin(),
  new webpack.ProvidePlugin({
    __: 'js/views_helpers/i18n/__',
  }),
  new webpack.ContextReplacementPlugin(
    /moment[\\/]locale$/,
    /^\.\/(en|es|fr|ja|zh-cn|zh-tw)$/
  ),
  new CheckerPlugin(),
  new ProgressBarPlugin(),
  new FriendlyErrorsWebpackPlugin({
    clearConsole: false,
  }),
]

if (!process.env.SERVER_RENDERING && process.env.MODE !== 'v4-style') {
  // plugins.push(new webpack.BannerPlugin(shim, { raw: true, entryOnly: true }))
  plugins.push(
    new webpack.BannerPlugin({ banner: shim, raw: true, entryOnly: true })
  )
}

const webcubeBabelrc = JSON.parse(
  fs.readFileSync(path.join(__dirname, './node_modules/webcube/.babelrc'))
)
webcubeBabelrc.plugins.splice(
  webcubeBabelrc.plugins.indexOf('add-module-exports'),
  1
)

const cacheLoader = {
  loader: 'cache-loader',
  options: {
    cacheDirectory: path.resolve(__dirname, './tmp/cache/cache-loader'),
  },
}

const config = {
  context: __dirname,
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015', 'env'],
          },
        },
        include: [path.join(__dirname, 'miniprogram', 'src')],
      },
      {
        test: /\.tsx?/,
        use: [cacheLoader, 'babel-loader?cacheDirectory'],
        include: [
          path.join(__dirname, 'fe'),
          path.join(__dirname, 'common'),
          path.join(__dirname, 'component-kit', 'src'),
        ],
      },
      {
        test: /\.tsx?/,
        use: ['awesome-typescript-loader?transpileOnly=true'],
        include: [path.join(__dirname, 'fe'), path.join(__dirname, 'common')],
      },
      {
        test: /\.tsx?/,
        use: ['ts-loader'],
        include: [path.join(__dirname, 'component-kit', 'src')],
      },
      {
        test: /\.css$/,
        use: [cacheLoader, 'style-loader', 'css-loader'],
        include: [
          path.join(__dirname, 'fe'),
          path.join(__dirname, 'common'),
          path.join(__dirname, 'vendor', 'assets', 'stylesheets'),
          path.join(__dirname, 'component-kit', 'src'),
          path.join(__dirname, 'node_modules', 'react-select'),
        ],
      },
      {
        test: /\.po/,
        use: [cacheLoader, 'json-loader', 'po-loader?format=jed1.x'],
        include: [path.join(__dirname, 'fe', 'locales')],
      },
      {
        test: /\.hrt/,
        use: [
          cacheLoader,
          'react-templates-loader?modules=commonjs&targetVersion=0.14.0',
          'hamlc-loader',
        ],
        include: [path.join(__dirname, 'fe')],
      },
      {
        test: /\.cjsx$/,
        use: [
          cacheLoader,
          'babel-loader?cacheDirectory',
          'coffee-loader',
          'cjsx-loader',
        ],
        include: [path.join(__dirname, 'fe')],
      },
      {
        test: /\.es6$/,
        use: [cacheLoader, 'babel-loader?cacheDirectory'],
        include: [path.join(__dirname, 'fe'), path.join(__dirname, 'common')],
      },
      {
        test: /\.js$/,
        use: [cacheLoader, 'babel-loader?cacheDirectory'],
        include: [path.join(__dirname, 'miniprogram', 'src')],
      },
      {
        test: /\.jsx?$/,
        use: [
          cacheLoader,
          {
            loader: 'babel-loader',
            options: Object.assign(webcubeBabelrc, {
              babelrc: false,
              cacheDirectory: true,
            }),
          },
        ],
        include: [
          path.join(__dirname, 'fe-packages', 'webcube'),
          path.join(__dirname, 'fe-packages', 'redux-cube'),
          path.join(__dirname, 'fe-packages', 'redux-cube-with-immutable'),
          path.join(__dirname, 'fe-packages', 'redux-cube-with-persist'),
          path.join(__dirname, 'fe-packages', 'redux-cube-with-router'),
          path.join(__dirname, 'fe-packages', 'redux-cube-with-router-legacy'),
          path.join(__dirname, 'fe-packages', 'redux-source-utils'),
          path.join(__dirname, 'fe-packages', 'redux-source'),
          path.join(__dirname, 'fe-packages', 'redux-source-immutable'),
          path.join(__dirname, 'fe-packages', 'redux-source-connect'),
          path.join(__dirname, 'fe-packages', 'redux-source-connect-immutable'),
          path.join(__dirname, 'fe-packages', 'redux-source-with-notify'),
          path.join(__dirname, 'fe-packages', 'redux-source-with-block-ui'),
          path.join(__dirname, 'fe-packages', 'hifetch'),
        ],
      },
      {
        test: /\.coffee$/,
        use: [cacheLoader, 'babel-loader?cacheDirectory', 'coffee-loader'],
        include: [path.join(__dirname, 'fe')],
      },
      {
        test: require.resolve('react'),
        use: 'expose-loader?React',
      },
      {
        test: /cloudinary\.js$/, // disable AMD for cloudinary otherwise it will not be defined as a jquery plugin
        use: [cacheLoader, 'imports-loader?define=>false'],
        include: [path.join(__dirname, 'node_modules', 'cloudinary')],
      },
      {
        test: /\.less$/,
        use: [
          cacheLoader,
          'isomorphic-style-loader',
          'css-loader',
          'less-loader',
        ],
        include: [
          path.join(__dirname, 'fe/js/components/amp'),
          path.join(__dirname, 'component-kit/src'),
        ],
      },
      {
        test: /\.less$/,
        use: [
          cacheLoader,
          'style-loader',
          'css-loader',
          'less-loader?strictMath&noIeCompat',
        ],
        include: [path.join(__dirname, 'fe')],
        exclude: [
          path.join(__dirname, 'fe/js/components/amp'),
          path.join(__dirname, 'fe/styles'),
        ],
      },
      {
        test: /\.less$/,
        loaders: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [{ loader: 'happypack/loader?id=less' }],
        }),
        include: [
          path.join(__dirname, 'fe/styles'),
          path.join(__dirname, 'vendor', 'assets', 'stylesheets'),
        ],
      },
      {
        test: /\.(jpe?g|png|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name:
                process.env.NODE_ENV === 'production'
                  ? '/images/[name].[hash].[ext]'
                  : 'images/[name].[ext]', //
            },
          },
        ],
        include: [path.join(__dirname, 'fe'), path.join(__dirname, 'public')],
      },
      {
        test: /\.(eot|svg|cur|woff2?|ttf)$/,
        loader: 'file-loader',
        options: {
          name:
            process.env.NODE_ENV === 'production'
              ? '/fonts/[name].[hash].[ext]'
              : 'fonts/[name].[ext]', //
        },
      },
    ],
  },

  resolve: {
    unsafeCache: true, // for speedup http://stackoverflow.com/questions/29267084/how-to-improve-webpack-babel-build-performance-without-using-the-watch-feature
    extensions: [
      '.hrt',
      '.cjsx',
      '.coffee',
      '.js',
      '.jsx',
      '.es6',
      '.ts',
      '.tsx',
      '.less',
    ],
    alias: aliasMap,
    symlinks: true,
  },
  externals: {
    // require("jquery") is external and available
    //  on the global var jQuery
    BackEndI18n: 'I18n',
    routes: 'Routes',
    jquery: '$',
    $S: '$S',
    analytics: 'analytics',
    gaq: '_gaq',
    Keen: 'Keen',
    bugsnag: 'Bugsnag',
    pingpp: 'pingpp',
    CKEDITOR: 'CKEDITOR',
    recurly: 'recurly',
  },
  plugins,
  node: {
    fs: 'empty',
  },
  // addVendor: function(name, path) {
  //   this.resolve.alias[name] = path
  //   this.module.noParse.push(new RegExp(name))
  // },
  stats: {
    assets: false,
    version: false,
    timings: true,
    hash: true,
    chunks: false,
    chunkModules: false,
    errorDetails: true,
    reasons: false,
    colors: true,
  },
}

// config.addVendor('lodash', __dirname + '/fe/js/vendor/lodash.custom.js')

module.exports = config
