const path = require('path');
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const { rootDir, env, version, target, staticPath } = require('../helpers/const');

const assetTarget = 'default';

module.exports = {
  context: rootDir,

  name: 'server',
  mode: 'development',
  target: 'node',

  devtool: 'eval-source-map',

  watchOptions: {
    ignored: /node_modules/,
    aggregateTimeout: 250,
    poll: 500
  },

  entry: [path.resolve(rootDir, './src/application/server/renderer.tsx')],

  output: {
    path: path.resolve(rootDir, './build/server'),
    filename: 'renderer.js',
    assetModuleFilename: 'assets/[name].[hash:8][ext]',
    publicPath: `${staticPath}/${assetTarget}/`,
    library: {
      type: 'commonjs2'
    },
    pathinfo: false
  },

  cache: {
    type: 'filesystem',
    buildDependencies: {
      configs: [__filename]
    }
  },

  optimization: {
    removeAvailableModules: false,
    removeEmptyChunks: false
  },

  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
    alias: {
      '@root': path.resolve(rootDir, './'),
      '@game': path.resolve(rootDir, './src'),
      '@server': path.resolve(rootDir, '../game-server/src'),
      '@api': path.resolve(rootDir, '../game-api/src'),
      '@map': path.resolve(rootDir, '../map/src'),
      '@core': path.resolve(rootDir, '../core/src'),

      '_service': path.resolve(rootDir, './src'),
      '_build': path.resolve(rootDir, './build'),

      'react': path.resolve(rootDir, './node_modules/react'),
      'react-dom': path.resolve(rootDir, './node_modules/react-dom'),
      '@loadable': path.resolve(rootDir, './node_modules/@loadable'),
      '@babel': path.resolve(rootDir, './node_modules/@babel'),
      'svg-sprite-loader': path.resolve(rootDir, './node_modules/svg-sprite-loader')
    }
  },

  // Игнорируем built-in модули такие как: path, fs, etc.
  // https://github.com/liady/webpack-node-externals
  externalsPresets: {
    node: true
  },

  externals: [nodeExternals()],

  module: {
    generator: {
      'asset': {
        publicPath: staticPath,
        outputPath: '../client/default'
      },
      'asset/resource': {
        publicPath: staticPath,
        outputPath: '../client/default'
      }
    },

    rules: [
      // JavaScript
      {
        test: /\.m?js$/,
        exclude: /node_modules/,
        type: 'javascript/auto'
      },
      // TypeScript
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              cacheDirectory: true,
              presets: [
                [
                  '@babel/preset-env',
                  {
                    targets: {
                      node: 'current'
                    }
                  }
                ]
              ]
            }
          }
        ]
      },
      // CSS & Sass
      {
        test: /\.(?:s[ac]|c)ss$/,
        loader: 'null-loader'
      },
      // Images
      {
        test: /\.(?:ico|gif|png|jpg|jpeg|svg)$/i,
        type: 'asset/resource'
      }
    ]
  },

  plugins: [
    new webpack.EnvironmentPlugin({
      NODE_ENV: env,
      STATIC_PATH: staticPath,
      APP_VERSION: version,
      PLATFORM: 'server',
      TARGET: target,
      API_HOST: 'localhost:3001',
      SERVER_MSGPACK: 0,
    }),

    new ForkTsCheckerWebpackPlugin({
      typescript: {
        mode: 'write-references'
      }
    }),

    new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: 'chunks/[id].css'
    }),

    new webpack.optimize.LimitChunkCountPlugin({
      maxChunks: 1
    }),

    new webpack.ProgressPlugin()
  ]
};
