/**
 * This file is part of the NocoBase (R) project.
 * Copyright (c) 2020-2024 NocoBase Co., Ltd.
 * Authors: NocoBase Team.
 *
 * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
 * For more information, please refer to: https://www.nocobase.com/agreement.
 */

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 plugin_exports = {};
__export(plugin_exports, {
  default: () => PluginCollectionFDWServer
});
module.exports = __toCommonJS(plugin_exports);
var import_database = require("@nocobase/database");
var import_server = require("@nocobase/server");
var import_mariadb_to_mariadb = require("./bridges/mariadb-to-mariadb");
var import_mysql_to_mysql = require("./bridges/mysql-to-mysql");
var import_pg_to_pg = require("./bridges/pg-to-pg");
var import_remote_local_bridge = require("./bridges/remote-local-bridge");
var import_foreign_data_collection = require("./foreign-data-collection");
var import_database_server = require("./models/database-server");
var import_tables = __toESM(require("./resourcers/tables"));
class PluginCollectionFDWServer extends import_server.Plugin {
  async beforeLoad() {
    import_remote_local_bridge.RemoteLocalBridgeFactory.registerBridge("postgres", "postgres", import_pg_to_pg.PgToPgBridge);
    import_remote_local_bridge.RemoteLocalBridgeFactory.registerBridge("mariadb", "mariadb", import_mariadb_to_mariadb.MariadbToMariadbBridge);
    import_remote_local_bridge.RemoteLocalBridgeFactory.registerBridge("mysql", "mysql", import_mysql_to_mysql.MySQLToMySQLBridge);
    const app = this.app;
    this.app.db.registerModels({
      DatabaseServerModel: import_database_server.DatabaseServerModel
    });
    this.app.db.on("databaseServers.beforeCreate", async (model, options) => {
      if (!model.get("dialect")) {
        const dialect = this.db.options.dialect;
        model.set("dialect", dialect);
      }
      model.setApp(this.app);
      await model.createServer(options);
    });
    this.app.db.on("databaseServers.afterUpdate", async (model, options) => {
      model.setApp(this.app);
      await model.updateServer(options);
    });
    this.app.db.on("databaseServers.afterDestroy", async (model, options) => {
      model.setApp(this.app);
      await model.destroyServer(options);
    });
    this.app.resourceManager.define(import_tables.default);
    this.app.db.collectionFactory.registerCollectionType(
      import_foreign_data_collection.ForeignDataCollection,
      import_foreign_data_collection.ForeignDataCollection.registerOptions(this)
    );
    this.app.resourceManager.registerActionHandlers({
      async ["databaseServers:testConnection"](ctx, next) {
        const values = ctx.app.environment.renderJsonTemplate(ctx.action.params.values || {});
        const db = new import_database.Database({
          dialect: app.db.options.dialect,
          ...values
        });
        try {
          await db.sequelize.authenticate();
        } catch (error) {
          throw new Error(`Unable to connect to the remote database: ${error.message}`);
        }
        ctx.body = {
          success: true
        };
        await next();
      }
    });
  }
  async load() {
    this.app.acl.registerSnippet({
      name: "pm.data-source-manager.collection-fdw",
      actions: ["databaseServers:*", "databaseServers.tables:*"]
    });
  }
  async beforeEnable() {
    if (this.db.inDialect("sqlite")) {
      throw new Error("sqlite does not support foreign data wrapper");
    }
  }
}
