"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var lint_command_exports = {};
__export(lint_command_exports, {
  LintCommand: () => LintCommand
});
module.exports = __toCommonJS(lint_command_exports);
var import_sdk = require("@botpress/sdk");
var apiUtils = __toESM(require("../api"));
var errors = __toESM(require("../errors"));
var import_bot_linter = require("../linter/bot-linter");
var import_integration_linter = require("../linter/integration-linter");
var import_interface_linter = require("../linter/interface-linter");
var import_project_command = require("./project-command");
class LintCommand extends import_project_command.ProjectCommand {
  async run() {
    const { projectType, resolveProjectDefinition } = this.readProjectDefinitionFromFS();
    const projectDef = await resolveProjectDefinition();
    if (projectDef.bpLintDisabled) {
      this.logger.warn(
        'Linting is disabled for this project because of a bplint directive. To enable linting, remove the "bplint-disable" directive from the project definition file'
      );
      return;
    }
    switch (projectType) {
      case "integration": {
        const projectDef2 = await resolveProjectDefinition();
        return this._runLintForIntegration(projectDef2.definition);
      }
      case "bot": {
        const projectDef2 = await resolveProjectDefinition();
        return this._runLintForBot(projectDef2.definition);
      }
      case "interface": {
        const projectDef2 = await resolveProjectDefinition();
        return this._runLintForInterface(projectDef2.definition);
      }
      default:
        throw new errors.UnsupportedProjectType();
    }
  }
  async _runLintForInterface(definition) {
    for (const [actionName, actionDef] of Object.entries(definition.actions)) {
      definition.actions[actionName] = this._dereferenceActionDefinition(actionDef);
    }
    for (const [eventName, eventDef] of Object.entries(definition.events)) {
      definition.events[eventName] = this._dereferenceEventDefinition(eventDef);
    }
    const parsedInterfaceDefinition = await apiUtils.prepareCreateInterfaceBody(definition);
    const linter = new import_interface_linter.InterfaceLinter(parsedInterfaceDefinition);
    await linter.lint();
    linter.logResults(this.logger);
    if (linter.hasErrors()) {
      throw new errors.BotpressCLIError("Interface definition contains linting errors");
    }
    this.logger.success("Interface definition is valid");
  }
  async _runLintForBot(definition) {
    const strippedDefinition = this._stripAutoGeneratedContentFromBot(definition);
    const parsedBotDefinition = await apiUtils.prepareCreateBotBody(strippedDefinition);
    const linter = new import_bot_linter.BotLinter(parsedBotDefinition);
    await linter.lint();
    linter.logResults(this.logger);
    if (linter.hasErrors()) {
      throw new errors.BotpressCLIError("Bot definition contains linting errors");
    }
    this.logger.success("Bot definition is valid");
  }
  _stripAutoGeneratedContentFromBot(definition) {
    return {
      ...definition,
      integrations: {}
    };
  }
  async _runLintForIntegration(definition) {
    const strippedDefinition = this._stripAutoGeneratedContentFromIntegration(definition);
    const parsedIntegrationDefinition = await this.prepareCreateIntegrationBody(strippedDefinition);
    const linter = new import_integration_linter.IntegrationLinter({ ...parsedIntegrationDefinition, secrets: strippedDefinition.secrets });
    await linter.lint();
    linter.logResults(this.logger);
    if (linter.hasErrors()) {
      throw new errors.BotpressCLIError("Integration definition contains linting errors");
    }
    this.logger.success("Integration definition is valid");
  }
  _stripAutoGeneratedContentFromIntegration(definition) {
    const { actionNames, eventNames } = this._getAutoGeneratedContentOfIntegration(definition);
    return {
      ...definition,
      actions: Object.fromEntries(Object.entries(definition.actions ?? {}).filter(([key]) => !actionNames.has(key))),
      events: Object.fromEntries(Object.entries(definition.events ?? {}).filter(([key]) => !eventNames.has(key)))
    };
  }
  _getAutoGeneratedContentOfIntegration(definition) {
    const actionNames = /* @__PURE__ */ new Set();
    const eventNames = /* @__PURE__ */ new Set();
    const interfacesStatements = definition.interfaces ?? {};
    for (const iface of Object.values(interfacesStatements)) {
      for (const actionDefinition of Object.values(iface.actions)) {
        actionNames.add(actionDefinition.name);
      }
      for (const eventDefinition of Object.values(iface.events)) {
        eventNames.add(eventDefinition.name);
      }
    }
    return { actionNames, eventNames };
  }
  _dereferenceActionDefinition = (actionDef) => {
    const inputRefs = actionDef.input.schema.getReferences();
    const outputRefs = actionDef.output.schema.getReferences();
    const inputRefSchemas = Object.fromEntries(inputRefs.map((ref) => [ref, this._replaceRef(ref)]));
    const outputRefSchemas = Object.fromEntries(outputRefs.map((ref) => [ref, this._replaceRef(ref)]));
    actionDef.input.schema = actionDef.input.schema.dereference(inputRefSchemas);
    actionDef.output.schema = actionDef.output.schema.dereference(outputRefSchemas);
    return actionDef;
  };
  _dereferenceEventDefinition = (eventDef) => {
    const refs = eventDef.schema.getReferences();
    const refSchemas = Object.fromEntries(refs.map((ref) => [ref, this._replaceRef(ref)]));
    eventDef.schema = eventDef.schema.dereference(refSchemas);
    return eventDef;
  };
  _replaceRef = (refUri) => import_sdk.z.object({}).title(refUri).describe(refUri);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  LintCommand
});
//# sourceMappingURL=lint-command.js.map
