/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
#pragma once

#include <chrono>
#include <memory>
#include <system_error>
#include <vector>

#include "AsyncCallback.h"
#include "CredentialsProvider.h"
#include "ErrorCode.h"
#include "LocalTransactionStateChecker.h"
#include "Logger.h"
#include "MQMessage.h"
#include "MQSelector.h"
#include "SendResult.h"

ROCKETMQ_NAMESPACE_BEGIN

/**
 * This class employs pointer-to-implementation paradigm to achieve the goal of stable ABI.
 * Refer https://en.cppreference.com/w/cpp/language/pimpl for an explanation.
 */
class ProducerImpl;

class DefaultMQProducer {
public:
  explicit DefaultMQProducer(const std::string& group_name);

  ~DefaultMQProducer() = default;

  void start();

  void shutdown();

  /**
   * Acquire previous send timeout in milliseconds.
   * @return Send timeout in milliseconds
   */
  std::chrono::milliseconds getSendMsgTimeout() const;

  /**
   * Set default send message timeout in milliseconds.
   * @param timeout_millis Timeout used when sending messages.
   */
  void setSendMsgTimeout(std::chrono::milliseconds timeout);

  SendResult send(MQMessage& message, const std::string& message_group);

  /**
   * Send message in synchronous manner.
   * @param message  Message to send.
   * @param filter_active_broker Do NOT rely on this parameter. it has been deprecated.
   */
  SendResult send(const MQMessage& message, bool filter_active_broker = true);

  SendResult send(const MQMessage& message, std::error_code& ec) noexcept;

  SendResult send(MQMessage& message, const MQMessageQueue& message_queue);
  SendResult send(MQMessage& message, MessageQueueSelector* selector, void* arg);

  /**
   * @brief This function is deprecated.
   *
   * @param message
   * @param selector
   * @param arg
   * @param retry_times retry_times is ignored with respect to member retry_times setting.
   * @param select_active_broker
   * @return SendResult
   */
  SendResult send(MQMessage& message, MessageQueueSelector* selector, void* arg, int retry_times,
                  bool select_active_broker = false);

  /**
   * Send message in asynchronous manner.
   * @param message  Message to send.
   * @param send_callback Callback to execute on completion of message sending.
   * @param select_active_broker Do NOT rely on this parameter. it has been deprecated.
   */
  void send(const MQMessage& message, SendCallback* send_callback, bool select_active_broker = false);
  void send(MQMessage& message, const MQMessageQueue& message_queue, SendCallback* send_callback);
  void send(MQMessage& message, MessageQueueSelector* selector, void* arg, SendCallback* send_callback);

  /**
   * send message in Oneway(The implementation is simply ignore the result of send message in synchronous).
   * @param message  Message to send.
   * @param select_active_broker Do NOT rely on this parameter. it has been deprecated.
   */
  void sendOneway(const MQMessage& message, bool select_active_broker = false);
  void sendOneway(MQMessage& message, const MQMessageQueue& message_queue);
  void sendOneway(MQMessage& message, MessageQueueSelector* selector, void* arg);

  void setLocalTransactionStateChecker(LocalTransactionStateCheckerPtr checker);

  void setNamesrvAddr(const std::string& name_server_address_list);

  void setNameServerListDiscoveryEndpoint(const std::string& discovery_endpoint);

  void setGroupName(const std::string& group_name);

  void setInstanceName(const std::string& instance_name);

  void enableTracing(bool enabled);

  bool isTracingEnabled();

  /**
   * Number of attempts before claiming a send action as failure. By default, 3 attempts will be performed for sync and
   * async send methods.
   *
   * @return
   */
  int getMaxAttemptTimes() const;

  void setMaxAttemptTimes(int max_attempt_times);

  std::vector<MQMessageQueue> getTopicMessageQueueInfo(const std::string& topic);

  void setUnitName(std::string unit_name);

  const std::string& getUnitName();

  uint32_t compressBodyThreshold() const;
  void compressBodyThreshold(uint32_t threshold);

  void setResourceNamespace(const std::string& resource_namespace);

  void setCredentialsProvider(CredentialsProviderPtr credentials_provider);

  void setRegion(const std::string& region);

  TransactionPtr prepare(MQMessage& message);

private:
  std::shared_ptr<ProducerImpl> impl_;
};

ROCKETMQ_NAMESPACE_END