/*
 * Copyright (c) 2017, 2025, Oracle and/or its affiliates.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2.0,
 * as published by the Free Software Foundation.
 *
 * This program is designed to work with certain software (including
 * but not limited to OpenSSL) that is licensed under separate terms,
 * as designated in a particular file or component or in included license
 * documentation.  The authors of MySQL hereby grant you an additional
 * permission to link the program and your derivative works with the
 * separately licensed software that they have either included with
 * the program or referenced in the documentation.
 *
 * This program is distributed in the hope that it will be useful,  but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 * the GNU General Public License, version 2.0, for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef MODULES_UTIL_MOD_UTIL_H_
#define MODULES_UTIL_MOD_UTIL_H_

#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "modules/mod_extensible_object.h"
#include "modules/util/binlog/dump_binlogs_options.h"
#include "modules/util/binlog/load_binlogs_options.h"
#include "modules/util/copy/copy_instance_options.h"
#include "modules/util/copy/copy_schemas_options.h"
#include "modules/util/copy/copy_tables_options.h"
#include "modules/util/dump/dump_instance_options.h"
#include "modules/util/dump/dump_schemas_options.h"
#include "modules/util/dump/dump_tables_options.h"
#include "modules/util/dump/export_table_options.h"
#include "modules/util/import_table/import_table_options.h"
#include "modules/util/load/load_dump_options.h"
#include "modules/util/upgrade_check.h"
#include "mysqlshdk/libs/db/connection_options.h"
#include "mysqlshdk/libs/utils/document_parser.h"

namespace shcore {
class IShell_core;
}

namespace mysqlsh {

struct Import_json_options {
  std::string schema;
  std::string table;
  std::string collection;
  std::string table_column;
  shcore::Document_reader_options doc_reader;

  static const shcore::Option_pack_def<Import_json_options> &options();
};

/**
 * \defgroup util util
 * \ingroup ShellAPI
 * $(UTIL_BRIEF)
 */
class SHCORE_PUBLIC Util : public Extensible_object {
 public:
  explicit Util(shcore::IShell_core *owner);

  std::string class_name() const override { return "Util"; };

#if DOXYGEN_JS
  Undefined checkForServerUpgrade(ConnectionData connectionData,
                                  Dictionary options);
  Undefined checkForServerUpgrade(Dictionary options);
#elif DOXYGEN_PY
  None check_for_server_upgrade(ConnectionData connectionData, dict options);
  None check_for_server_upgrade(dict options);
#endif
  void check_for_server_upgrade(
      const std::optional<mysqlshdk::db::Connection_options>
          &connection_options = {},
      const upgrade_checker::Upgrade_check_options &options = {});

#if DOXYGEN_JS
  Undefined importJson(String file, Dictionary options);
#elif DOXYGEN_PY
  None import_json(str file, dict options);
#endif
  void import_json(const std::string &file,
                   const Import_json_options &options = {});

#if DOXYGEN_JS
  Undefined importTable(List urls, Dictionary options);
#elif DOXYGEN_PY
  None import_table(list urls, dict options);
#endif
  void import_table_file(const std::string &filename,
                         const import_table::Import_table_option_pack &options);
  void import_table_files(
      const std::vector<std::string> &filenames,
      const import_table::Import_table_option_pack &options);

#if DOXYGEN_JS
  Undefined loadDump(String url, Dictionary options);
#elif DOXYGEN_PY
  None load_dump(str url, dict options);
#endif
  void load_dump(const std::string &url, Load_dump_options &&options);

#if DOXYGEN_JS
  Undefined exportTable(String table, String outputUrl, Dictionary options);
#elif DOXYGEN_PY
  None export_table(str table, str outputUrl, dict options);
#endif
  void export_table(const std::string &table, const std::string &file,
                    dump::Export_table_options &&options);

#if DOXYGEN_JS
  Undefined dumpTables(String schema, List tables, String outputUrl,
                       Dictionary options);
#elif DOXYGEN_PY
  None dump_tables(str schema, list tables, str outputUrl, dict options);
#endif
  void dump_tables(const std::string &schema,
                   const std::vector<std::string> &tables,
                   const std::string &directory,
                   dump::Dump_tables_options &&options);

#if DOXYGEN_JS
  Undefined dumpSchemas(List schemas, String outputUrl, Dictionary options);
#elif DOXYGEN_PY
  None dump_schemas(list schemas, str outputUrl, dict options);
#endif
  void dump_schemas(const std::vector<std::string> &schemas,
                    const std::string &directory,
                    dump::Dump_schemas_options &&options);

#if DOXYGEN_JS
  Undefined dumpInstance(String outputUrl, Dictionary options);
#elif DOXYGEN_PY
  None dump_instance(str outputUrl, dict options);
#endif
  void dump_instance(const std::string &directory,
                     dump::Dump_instance_options &&options);

#if DOXYGEN_JS
  Undefined copyInstance(ConnectionData connectionData, Dictionary options);
#elif DOXYGEN_PY
  None copy_instance(ConnectionData connectionData, dict options);
#endif
  void copy_instance(
      const mysqlshdk::db::Connection_options &connection_options,
      copy::Copy_instance_options &&options = {});

#if DOXYGEN_JS
  Undefined copySchemas(List schemas, ConnectionData connectionData,
                        Dictionary options);
#elif DOXYGEN_PY
  None copy_schemas(list schemas, ConnectionData connectionData, dict options);
#endif
  void copy_schemas(const std::vector<std::string> &schemas,
                    const mysqlshdk::db::Connection_options &connection_options,
                    copy::Copy_schemas_options &&options = {});

#if DOXYGEN_JS
  Undefined copyTables(String schema, List tables,
                       ConnectionData connectionData, Dictionary options);
#elif DOXYGEN_PY
  None copy_tables(str schema, list tables, ConnectionData connectionData,
                   dict options);
#endif
  void copy_tables(const std::string &schema,
                   const std::vector<std::string> &tables,
                   const mysqlshdk::db::Connection_options &connection_options,
                   copy::Copy_tables_options &&options = {});

#if DOXYGEN_JS
  Undefined dumpBinlogs(String outputUrl, Dictionary options);
#elif DOXYGEN_PY
  None dump_binlogs(str outputUrl, dict options);
#endif
  void dump_binlogs(const std::string &url,
                    binlog::Dump_binlogs_options &&options);

#if DOXYGEN_JS
  Undefined loadBinlogs(String url, Dictionary options);
#elif DOXYGEN_PY
  None load_binlogs(str url, dict options);
#endif
  void load_binlogs(const std::string &url,
                    binlog::Load_binlogs_options &&options);

 private:
  std::shared_ptr<mysqlshdk::db::ISession> global_session() const;

  shcore::IShell_core &_shell_core;
};

} /* namespace mysqlsh */

#endif  // MODULES_UTIL_MOD_UTIL_H_
