/**
 * Copyright 2024 Centreon
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * For more information : contact@centreon.com
 */

#ifndef CENTREON_AGENT_CHECK_EXEC_HH
#define CENTREON_AGENT_CHECK_EXEC_HH

#include "check.hh"
#include "com/centreon/common/process/process.hh"
#include "com/centreon/common/process/process_args.hh"

namespace com::centreon::agent {

/**
 * @brief check that executes a process (plugins)
 *
 */
class check_exec : public check {
  common::process_args::pointer _process_args;
  int _pid;

  std::shared_ptr<common::crypto::aes256> _credentials_decrypt;

 protected:
  using check::completion_handler;

 public:
  check_exec(
      const std::shared_ptr<asio::io_context>& io_context,
      const std::shared_ptr<spdlog::logger>& logger,
      time_point first_start_expected,
      const Service& serv,
      const std::string& command_line,
      const engine_to_agent_request_ptr& cnf,
      check::completion_handler&& handler,
      const checks_statistics::pointer& stat,
      const std::shared_ptr<common::crypto::aes256>& credentials_decrypt);

  static std::shared_ptr<check_exec> load(
      const std::shared_ptr<asio::io_context>& io_context,
      const std::shared_ptr<spdlog::logger>& logger,
      time_point first_start_expected,
      const Service& serv,
      const std::string& command_line,
      const engine_to_agent_request_ptr& cnf,
      check::completion_handler&& handler,
      const checks_statistics::pointer& stat,
      const std::shared_ptr<common::crypto::aes256>& credentials_decrypt);

  void start_check(const duration& timeout) override;

  void on_completion(unsigned running_index,
                     int exit_code,
                     int exit_status,
                     const std::string&);

  int get_pid() const { return _pid; }

  const common::process_args::pointer get_process_args() const {
    return _process_args;
  }
};

/**
 * @class check_dummy
 * @brief A class derived from check that is used to send an error message.
 *
 * This class represents a dummy check that sends a predefined error message.
 * It inherits from the check class and overrides the start_check method.
 *
 * @param io_context Shared pointer to the ASIO io_context.
 * @param logger Shared pointer to the spdlog logger.
 * @param first_start_expected The expected start time of the first check.
 * @param serv The service name.
 * @param output The predefined error message to be sent.
 * @param cnf Configuration for the engine to agent request.
 * @param handler Completion handler for the check.
 * @param stat Pointer to the checks statistics.
 */
class check_dummy : public check {
  std::string _output;

 protected:
  using check::completion_handler;

 public:
  check_dummy(const std::shared_ptr<asio::io_context>& io_context,
              const std::shared_ptr<spdlog::logger>& logger,
              time_point first_start_expected,
              const Service& serv,
              const std::string& output,
              const engine_to_agent_request_ptr& cnf,
              check::completion_handler&& handler,
              const checks_statistics::pointer& stat);

  static std::shared_ptr<check_dummy> load(
      const std::shared_ptr<asio::io_context>& io_context,
      const std::shared_ptr<spdlog::logger>& logger,
      time_point first_start_expected,
      const Service& serv,
      const std::string& output,
      const engine_to_agent_request_ptr& cnf,
      check::completion_handler&& handler,
      const checks_statistics::pointer& stat);

  void start_check(const duration& timeout) override;

  std::string get_output() { return _output; }
};

/**
 * @brief A custom check that extends the check_exec class.
 * This check is designed to execute a custom command line
 * built from provided arguments.
 */
class check_custom : public check_exec {
 public:
  check_custom(
      const std::shared_ptr<asio::io_context>& io_context,
      const std::shared_ptr<spdlog::logger>& logger,
      time_point first_start_expected,
      const Service& serv,
      const rapidjson::Value& args,
      const engine_to_agent_request_ptr& cnf,
      check::completion_handler&& handler,
      const checks_statistics::pointer& stat,
      const std::shared_ptr<common::crypto::aes256>& credentials_decrypt);
};
}  // namespace com::centreon::agent

#endif
