"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
function _path() {
  const data = _interopRequireDefault(require("path"));
  _path = function () {
    return data;
  };
  return data;
}
function _utils() {
  const data = require("@parcel/utils");
  _utils = function () {
    return data;
  };
  return data;
}
function _logger() {
  const data = _interopRequireWildcard(require("@parcel/logger"));
  _logger = function () {
    return data;
  };
  return data;
}
function _diagnostic() {
  const data = _interopRequireWildcard(require("@parcel/diagnostic"));
  _diagnostic = function () {
    return data;
  };
  return data;
}
var _ParcelConfig = _interopRequireDefault(require("./ParcelConfig"));
var _UncommittedAsset = _interopRequireDefault(require("./UncommittedAsset"));
var _assetUtils = require("./assetUtils");
var _Asset = require("./public/Asset");
var _PluginOptions = _interopRequireDefault(require("./public/PluginOptions"));
var _summarizeRequest = _interopRequireDefault(require("./summarizeRequest"));
var _projectPath = require("./projectPath");
function _profiler() {
  const data = require("@parcel/profiler");
  _profiler = function () {
    return data;
  };
  return data;
}
function _rust() {
  const data = require("@parcel/rust");
  _rust = function () {
    return data;
  };
  return data;
}
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
class Validation {
  allAssets = {};
  allValidators = {};
  constructor({
    config,
    dedicatedThread,
    options,
    requests,
    report,
    workerApi
  }) {
    this.dedicatedThread = dedicatedThread ?? false;
    this.options = options;
    this.parcelConfig = config;
    this.report = report;
    this.requests = requests;
    this.workerApi = workerApi;
  }
  async run() {
    let pluginOptions = new _PluginOptions.default(this.options);
    await this.buildAssetsAndValidators();
    await Promise.all(Object.keys(this.allValidators).map(async validatorName => {
      let assets = this.allAssets[validatorName];
      if (assets) {
        let plugin = this.allValidators[validatorName];
        let validatorLogger = new (_logger().PluginLogger)({
          origin: validatorName
        });
        let validatorTracer = new (_profiler().PluginTracer)({
          origin: validatorName,
          category: 'validator'
        });
        let validatorResults = [];
        try {
          // If the plugin supports the single-threading validateAll method, pass all assets to it.
          if (plugin.validateAll && this.dedicatedThread) {
            validatorResults = await plugin.validateAll({
              assets: assets.map(asset => new _Asset.Asset(asset)),
              options: pluginOptions,
              logger: validatorLogger,
              tracer: validatorTracer,
              resolveConfigWithPath: (configNames, assetFilePath) => (0, _utils().resolveConfig)(this.options.inputFS, assetFilePath, configNames, this.options.projectRoot)
            });
          }

          // Otherwise, pass the assets one-at-a-time
          else if (plugin.validate && !this.dedicatedThread) {
            await Promise.all(assets.map(async input => {
              let config = null;
              let publicAsset = new _Asset.Asset(input);
              if (plugin.getConfig) {
                config = await plugin.getConfig({
                  asset: publicAsset,
                  options: pluginOptions,
                  logger: validatorLogger,
                  tracer: validatorTracer,
                  resolveConfig: configNames => (0, _utils().resolveConfig)(this.options.inputFS, publicAsset.filePath, configNames, this.options.projectRoot)
                });
              }
              let validatorResult = await plugin.validate({
                asset: publicAsset,
                options: pluginOptions,
                config,
                logger: validatorLogger,
                tracer: validatorTracer
              });
              validatorResults.push(validatorResult);
            }));
          }
          this.handleResults(validatorResults);
        } catch (e) {
          throw new (_diagnostic().default)({
            diagnostic: (0, _diagnostic().errorToDiagnostic)(e, {
              origin: validatorName
            })
          });
        }
      }
    }));
  }
  async buildAssetsAndValidators() {
    // Figure out what validators need to be run, and group the assets by the relevant validators.
    await Promise.all(this.requests.map(async request => {
      this.report({
        type: 'validation',
        filePath: (0, _projectPath.fromProjectPath)(this.options.projectRoot, request.filePath)
      });
      let asset = await this.loadAsset(request);
      let validators = await this.parcelConfig.getValidators(request.filePath);
      for (let validator of validators) {
        this.allValidators[validator.name] = validator.plugin;
        if (this.allAssets[validator.name]) {
          this.allAssets[validator.name].push(asset);
        } else {
          this.allAssets[validator.name] = [asset];
        }
      }
    }));
  }
  handleResults(validatorResults) {
    let warnings = [];
    let errors = [];
    validatorResults.forEach(result => {
      if (result) {
        warnings.push(...result.warnings);
        errors.push(...result.errors);
      }
    });
    if (errors.length > 0) {
      throw new (_diagnostic().default)({
        diagnostic: errors
      });
    }
    if (warnings.length > 0) {
      _logger().default.warn(warnings);
    }
  }
  async loadAsset(request) {
    let {
      filePath,
      env,
      code,
      sideEffects,
      query
    } = request;
    let {
      content,
      size,
      isSource
    } = await (0, _summarizeRequest.default)(this.options.inputFS, {
      filePath: (0, _projectPath.fromProjectPath)(this.options.projectRoot, request.filePath)
    });

    // If the transformer request passed code rather than a filename,
    // use a hash as the base for the id to ensure it is unique.
    let idBase = code != null ? (0, _rust().hashString)(code) : (0, _projectPath.fromProjectPathRelative)(filePath);
    return new _UncommittedAsset.default({
      idBase,
      value: (0, _assetUtils.createAsset)(this.options.projectRoot, {
        idBase,
        filePath: filePath,
        isSource,
        type: _path().default.extname((0, _projectPath.fromProjectPathRelative)(filePath)).slice(1),
        query,
        env: env,
        stats: {
          time: 0,
          size
        },
        sideEffects: sideEffects
      }),
      options: this.options,
      content
    });
  }
}
exports.default = Validation;