/**
 * 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.
 */
#include "PrometheusMetricsPublisher.h"

#include <utility>
#include <stdexcept>

#include "core/Resource.h"
#include "utils/StringUtils.h"
#include "utils/OsUtils.h"
#include "utils/Id.h"
#include "minifi-cpp/Exception.h"

namespace org::apache::nifi::minifi::extensions::prometheus {

PrometheusMetricsPublisher::PrometheusMetricsPublisher(const std::string &name, const utils::Identifier &uuid, std::unique_ptr<MetricsExposer> exposer)
  : state::MetricsPublisherImpl(name, uuid),
    exposer_(std::move(exposer)) {}

void PrometheusMetricsPublisher::initialize(const std::shared_ptr<Configure>& configuration, const std::shared_ptr<state::response::ResponseNodeLoader>& response_node_loader) {
  state::MetricsPublisherImpl::initialize(configuration, response_node_loader);
  if (!exposer_) {
    exposer_ = std::make_unique<PrometheusExposerWrapper>(readExposerConfig());
  }
  loadAgentIdentifier();
}

PrometheusExposerConfig PrometheusMetricsPublisher::readExposerConfig() const {
  gsl_Expects(configuration_);
  PrometheusExposerConfig config;
  if (auto port = configuration_->get(Configuration::nifi_metrics_publisher_prometheus_metrics_publisher_port)) {
    try {
      config.port = std::stoul(*port);
    } catch(const std::exception&) {
      throw Exception(GENERAL_EXCEPTION, "Port configured for Prometheus metrics publisher is invalid: '" + *port + "'");
    }
  } else {
    throw Exception(GENERAL_EXCEPTION, "Port not configured for Prometheus metrics publisher!");
  }

  if (auto cert = configuration_->get(Configuration::nifi_metrics_publisher_prometheus_metrics_publisher_certificate)) {
    config.certificate = *cert;
  }

  if (auto ca_cert = configuration_->get(Configuration::nifi_metrics_publisher_prometheus_metrics_publisher_ca_certificate)) {
    config.ca_certificate = *ca_cert;
  }
  return config;
}

void PrometheusMetricsPublisher::clearMetricNodes() {
  std::lock_guard<std::mutex> lock(registered_metrics_mutex_);
  logger_->log_debug("Clearing all metric nodes.");
  if (gauge_collection_) {
    exposer_->removeMetric(gauge_collection_);
  }
  gauge_collection_.reset();
}

void PrometheusMetricsPublisher::loadMetricNodes(core::ProcessGroup* root) {
  logger_->log_debug("Loading all metric nodes.");
  std::lock_guard<std::mutex> lock(registered_metrics_mutex_);
  gauge_collection_ = std::make_shared<PublishedMetricGaugeCollection>(getMetricProviders(root), agent_identifier_);
  exposer_->registerMetric(gauge_collection_);
}

std::vector<gsl::not_null<std::shared_ptr<state::PublishedMetricProvider>>> PrometheusMetricsPublisher::getMetricProviders(core::ProcessGroup* root) const {
  gsl_Expects(response_node_loader_ && configuration_);
  std::vector<gsl::not_null<std::shared_ptr<state::PublishedMetricProvider>>> nodes;
  auto metric_classes_str = configuration_->get(minifi::Configuration::nifi_metrics_publisher_prometheus_metrics_publisher_metrics);
  if (!metric_classes_str || metric_classes_str->empty()) {
    metric_classes_str = configuration_->get(minifi::Configuration::nifi_metrics_publisher_metrics);
  }
  if (metric_classes_str && !metric_classes_str->empty()) {
    auto metric_classes = utils::string::splitAndTrimRemovingEmpty(*metric_classes_str, ",");
    std::unordered_set<std::string> unique_metric_classes{metric_classes.begin(), metric_classes.end()};
    for (const std::string& clazz : unique_metric_classes) {
      auto response_nodes = response_node_loader_->loadResponseNodes(clazz, root);
      if (response_nodes.empty()) {
        if (root) {
          logger_->log_warn("Metric class '{}' could not be loaded.", clazz);
        }
      } else {
        for (const auto& response_node : response_nodes) {
          logger_->log_info("Loading metric node '{}'", response_node->getName());
          nodes.push_back(response_node);
        }
      }
    }
  }
  return nodes;
}

void PrometheusMetricsPublisher::loadAgentIdentifier() {
  gsl_Expects(configuration_);
  auto agent_identifier = configuration_->get(Configure::nifi_metrics_publisher_agent_identifier);
  if (agent_identifier && !agent_identifier->empty()) {
    agent_identifier_ = *agent_identifier;
  } else {
    auto hostname = utils::OsUtils::getHostName();
    agent_identifier_ = hostname ? *hostname : "unknown-host-" + utils::IdGenerator::getIdGenerator()->generate().to_string();
  }
}

REGISTER_RESOURCE(PrometheusMetricsPublisher, DescriptionOnly);

}  // namespace org::apache::nifi::minifi::extensions::prometheus
