"use strict";

const fs = require('fs');

const path = require('path');

const _ = require('lodash');

const gzipSize = require('gzip-size');

const Logger = require('./Logger');

const Folder = require('./tree/Folder').default;

const {
  parseBundle
} = require('./parseUtils');

const {
  createAssetsFilter
} = require('./utils');

const FILENAME_QUERY_REGEXP = /\?.*$/u;
const FILENAME_EXTENSIONS = /\.(js|mjs)$/iu;
module.exports = {
  getViewerData,
  readStatsFromFile
};

function getViewerData(bundleStats, bundleDir, opts) {
  const {
    logger = new Logger(),
    excludeAssets = null
  } = opts || {};
  const isAssetIncluded = createAssetsFilter(excludeAssets); // Sometimes all the information is located in `children` array (e.g. problem in #10)

  if (_.isEmpty(bundleStats.assets) && !_.isEmpty(bundleStats.children)) {
    const {
      children
    } = bundleStats;
    bundleStats = bundleStats.children[0]; // Sometimes if there are additional child chunks produced add them as child assets,
    // leave the 1st one as that is considered the 'root' asset.

    for (let i = 1; i < children.length; i++) {
      children[i].assets.forEach(asset => {
        asset.isChild = true;
        bundleStats.assets.push(asset);
      });
    }
  } else if (!_.isEmpty(bundleStats.children)) {
    // Sometimes if there are additional child chunks produced add them as child assets
    bundleStats.children.forEach(child => {
      child.assets.forEach(asset => {
        asset.isChild = true;
        bundleStats.assets.push(asset);
      });
    });
  } // Picking only `*.js or *.mjs` assets from bundle that has non-empty `chunks` array


  bundleStats.assets = bundleStats.assets.filter(asset => {
    // Filter out non 'asset' type asset if type is provided (Webpack 5 add a type to indicate asset types)
    if (asset.type && asset.type !== 'asset') {
      return false;
    } // Removing query part from filename (yes, somebody uses it for some reason and Webpack supports it)
    // See #22


    asset.name = asset.name.replace(FILENAME_QUERY_REGEXP, '');
    return FILENAME_EXTENSIONS.test(asset.name) && !_.isEmpty(asset.chunks) && isAssetIncluded(asset.name);
  }); // Trying to parse bundle assets and get real module sizes if `bundleDir` is provided

  let bundlesSources = null;
  let parsedModules = null;

  if (bundleDir) {
    bundlesSources = {};
    parsedModules = {};

    for (const statAsset of bundleStats.assets) {
      const assetFile = path.join(bundleDir, statAsset.name);
      let bundleInfo;

      try {
        bundleInfo = parseBundle(assetFile);
      } catch (err) {
        const msg = err.code === 'ENOENT' ? 'no such file' : err.message;
        logger.warn(`Error parsing bundle asset "${assetFile}": ${msg}`);
        continue;
      }

      bundlesSources[statAsset.name] = _.pick(bundleInfo, 'src', 'runtimeSrc');
      Object.assign(parsedModules, bundleInfo.modules);
    }

    if (_.isEmpty(bundlesSources)) {
      bundlesSources = null;
      parsedModules = null;
      logger.warn('\nNo bundles were parsed. Analyzer will show only original module sizes from stats file.\n');
    }
  }

  const assets = bundleStats.assets.reduce((result, statAsset) => {
    // If asset is a childAsset, then calculate appropriate bundle modules by looking through stats.children
    const assetBundles = statAsset.isChild ? getChildAssetBundles(bundleStats, statAsset.name) : bundleStats;
    const modules = assetBundles ? getBundleModules(assetBundles) : [];

    const asset = result[statAsset.name] = _.pick(statAsset, 'size');

    const assetSources = bundlesSources && _.has(bundlesSources, statAsset.name) ? bundlesSources[statAsset.name] : null;

    if (assetSources) {
      asset.parsedSize = Buffer.byteLength(assetSources.src);
      asset.gzipSize = gzipSize.sync(assetSources.src);
    } // Picking modules from current bundle script


    const assetModules = modules.filter(statModule => assetHasModule(statAsset, statModule)); // Adding parsed sources

    if (parsedModules) {
      const unparsedEntryModules = [];

      for (const statModule of assetModules) {
        if (parsedModules[statModule.id]) {
          statModule.parsedSrc = parsedModules[statModule.id];
        } else if (isEntryModule(statModule)) {
          unparsedEntryModules.push(statModule);
        }
      } // Webpack 5 changed bundle format and now entry modules are concatenated and located at the end of it.
      // Because of this they basically become a concatenated module, for which we can't even precisely determine its
      // parsed source as it's located in the same scope as all Webpack runtime helpers.


      if (unparsedEntryModules.length && assetSources) {
        if (unparsedEntryModules.length === 1) {
          // So if there is only one entry we consider its parsed source to be all the bundle code excluding code
          // from parsed modules.
          unparsedEntryModules[0].parsedSrc = assetSources.runtimeSrc;
        } else {
          // If there are multiple entry points we move all of them under synthetic concatenated module.
          _.pullAll(assetModules, unparsedEntryModules);

          assetModules.unshift({
            identifier: './entry modules',
            name: './entry modules',
            modules: unparsedEntryModules,
            size: unparsedEntryModules.reduce((totalSize, module) => totalSize + module.size, 0),
            parsedSrc: assetSources.runtimeSrc
          });
        }
      }
    }

    asset.modules = assetModules;
    asset.tree = createModulesTree(asset.modules);
    return result;
  }, {});
  return Object.entries(assets).map(([filename, asset]) => ({
    label: filename,
    isAsset: true,
    // Not using `asset.size` here provided by Webpack because it can be very confusing when `UglifyJsPlugin` is used.
    // In this case all module sizes from stats file will represent unminified module sizes, but `asset.size` will
    // be the size of minified bundle.
    // Using `asset.size` only if current asset doesn't contain any modules (resulting size equals 0)
    statSize: asset.tree.size || asset.size,
    parsedSize: asset.parsedSize,
    gzipSize: asset.gzipSize,
    groups: _.invokeMap(asset.tree.children, 'toChartData')
  }));
}

function readStatsFromFile(filename) {
  return JSON.parse(fs.readFileSync(filename, 'utf8'));
}

function getChildAssetBundles(bundleStats, assetName) {
  return (bundleStats.children || []).find(c => _(c.assetsByChunkName).values().flatten().includes(assetName));
}

function getBundleModules(bundleStats) {
  return _(bundleStats.chunks).map('modules').concat(bundleStats.modules).compact().flatten().uniqBy('id') // Filtering out Webpack's runtime modules as they don't have ids and can't be parsed (introduced in Webpack 5)
  .reject(isRuntimeModule).value();
}

function assetHasModule(statAsset, statModule) {
  // Checking if this module is the part of asset chunks
  return (statModule.chunks || []).some(moduleChunk => statAsset.chunks.includes(moduleChunk));
}

function isEntryModule(statModule) {
  return statModule.depth === 0;
}

function isRuntimeModule(statModule) {
  return statModule.moduleType === 'runtime';
}

function createModulesTree(modules) {
  const root = new Folder('.');
  modules.forEach(module => root.addModule(module));
  root.mergeNestedFolders();
  return root;
}