/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Diagnostic, Logger } from "@matter/general";
import { ModelTraversal } from "./ModelTraversal.js";
import { ModelValidator } from "./definition-validation/ModelValidator.js";
const logger = Logger.get("ValidateModel");
function ValidateModel(model) {
  const result = new ValidateModel.Result(model);
  function validate(model2) {
    const Validator = ModelValidator.validators[model2.tag];
    if (!Validator) {
      model2.error("UNKNOWN_MODEL_TYPE", `No validator for ${model2.tag}`);
      return;
    }
    try {
      new Validator(model2).validate();
    } catch (e) {
      console.error(`Error validating ${model2.path}`);
      throw e;
    }
    result.elementCount++;
    if (!model2.valid) {
      result.invalidElementCount++;
      if (model2.errors) {
        for (const error of model2.errors) {
          if (result.errorCounts[error.code]) {
            result.errorCounts[error.code]++;
          } else {
            result.errorCounts[error.code] = 1;
          }
          result.errors.push(error);
        }
      }
    }
    Logger.nest(() => {
      model2.children.forEach(validate);
    });
  }
  logger.info("Validating matter model");
  ModelTraversal.memoize(() => validate(model));
  return result;
}
((ValidateModel2) => {
  class Result {
    constructor(model) {
      this.model = model;
    }
    elementCount = 0;
    invalidElementCount = 0;
    errorCounts = {};
    errors = Array();
    get invalidElementPercent() {
      return (this.invalidElementCount / this.elementCount * 100).toPrecision(2);
    }
    report() {
      if (this.errors.length) {
        logger.error("*** Validation error summary ***");
        this.errors.forEach(
          (error) => logger.error(
            error.message,
            Diagnostic.dict({ code: error.code, xref: error.xref, src: error.source })
          )
        );
        logger.error("Error counts by code:");
        Logger.nest(() => {
          const codes = Object.keys(this.errorCounts).sort(
            (a, b) => a.localeCompare(b, void 0, { sensitivity: "base" })
          );
          for (const code of codes) {
            logger.error(`${code}: ${this.errorCounts[code]}`);
          }
        });
        logger.error(
          `*** Total ${this.errors.length} validation error${this.errors.length === 1 ? "" : "s"} ***`
        );
        logger.error(
          `*** Total ${this.invalidElementCount} invalid element${this.invalidElementCount === 1 ? "" : "s"} (${this.invalidElementPercent}%) ***`
        );
      } else {
        logger.info(`*** Validation successful ***`);
      }
      logger.debug(`*** Total ${this.elementCount} element${this.elementCount === 1 ? "" : "s"} ***`);
    }
  }
  ValidateModel2.Result = Result;
})(ValidateModel || (ValidateModel = {}));
export {
  ValidateModel
};
//# sourceMappingURL=ValidateModel.js.map
