/*
 * Copyright (c) 2021-2022, NVIDIA CORPORATION.
 *
 * 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.
 */
#pragma once

#include <cudf/io/datasource.hpp>

#include <librdkafka/rdkafkacpp.h>

#include <map>
#include <memory>
#include <string>

namespace cudf {
namespace io {
namespace external {
namespace kafka {

/**
 * @brief Python Callback function wrapper type used for Kafka OAuth events
 *
 * The KafkaConsumer calls the `kafka_oauth_callback_wrapper_type` when the existing
 * oauth token is considered expired by the KafkaConsumer. Typically that
 * means this will be invoked a single time when the KafkaConsumer is created
 * to get the initial token and then intermediately as the token becomes
 * expired.
 *
 * The callback function signature is:
 *     `std::map<std::string, std::string> kafka_oauth_callback_wrapper_type(void*)`
 *
 * The callback function returns a std::map<std::string, std::string>,
 * where the std::map consists of the Oauth token and its
 * linux epoch expiration time. Generally the token and expiration
 * time is retrieved from an external service by the callback.
 * Ex: [token, token_expiration_in_epoch]
 */
using kafka_oauth_callback_wrapper_type = std::map<std::string, std::string> (*)(void*);
using python_callable_type              = void*;

/**
 * @brief Callback to retrieve OAuth token from external source. Invoked when
 * token refresh is required.
 */
class python_oauth_refresh_callback : public RdKafka::OAuthBearerTokenRefreshCb {
 public:
  python_oauth_refresh_callback(kafka_oauth_callback_wrapper_type callback_wrapper,
                                python_callable_type python_callable);

  void oauthbearer_token_refresh_cb(RdKafka::Handle* handle, const std::string& oauthbearer_config);

 private:
  kafka_oauth_callback_wrapper_type callback_wrapper_;
  python_callable_type python_callable_;
};

}  // namespace kafka
}  // namespace external
}  // namespace io
}  // namespace cudf
