/** @file

  Calculate some derivative metrics (for convenience).

  @section license License

  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 <vector>

#include "DerivativeMetrics.h"

// ToDo: It's a little bizarre that we include this here, but it's the only way to get to RecSetRecord(). We should
// move that elsewhere... But other places in our core does the same thing.
#include "records/P_RecCore.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// This currently only supports one type of derivative metrics: Sums() of other, existing metrics. It's ok to add
// additional metrics here, and we prefer to call them proxy.process (since, hopefully in the future, traffic_manager dies).
//
static const std::vector<DerivativeSum> sum_metrics = {
  // Total bytes of client request body + headers
  {"proxy.process.http.user_agent_total_request_bytes",
   RECD_INT,
   {"proxy.process.http.user_agent_request_document_total_size", "proxy.process.http.user_agent_request_header_total_size"}},
  // Total bytes of client response body + headers
  {"proxy.process.http.user_agent_total_response_bytes",
   RECD_INT,
   {"proxy.process.http.user_agent_response_document_total_size", "proxy.process.http.user_agent_response_header_total_size"}},
  // Total bytes of origin server request body + headers
  {"proxy.process.http.origin_server_total_request_bytes",
   RECD_INT,
   {"proxy.process.http.origin_server_request_document_total_size", "proxy.process.http.origin_server_request_header_total_size"}},
  // Total bytes of origin server response body + headers
  {"proxy.process.http.origin_server_total_response_bytes",
   RECD_INT,
   {"proxy.process.http.origin_server_response_document_total_size",
    "proxy.process.http.origin_server_response_header_total_size"}},
  // Total bytes of client request and response (total traffic to and from clients)
  {"proxy.process.user_agent_total_bytes",
   RECD_INT,
   {"proxy.process.http.user_agent_total_request_bytes", "proxy.process.http.user_agent_total_response_bytes"}},
  // Total bytes of origin/parent request and response
  {"proxy.process.origin_server_total_bytes",
   RECD_INT,
   {"proxy.process.http.origin_server_total_request_bytes", "proxy.process.http.origin_server_total_response_bytes",
    "proxy.process.http.parent_proxy_request_total_bytes", "proxy.process.http.parent_proxy_response_total_bytes"}},
  // Total requests which are cache hits
  {"proxy.process.cache_total_hits",
   RECD_COUNTER,
   {"proxy.process.http.cache_hit_fresh", "proxy.process.http.cache_hit_revalidated", "proxy.process.http.cache_hit_ims",
    "proxy.process.http.cache_hit_stale_served"}},
  // Total requests which are cache misses
  {"proxy.process.cache_total_misses",
   RECD_COUNTER,
   {"proxy.process.http.cache_miss_cold", "proxy.process.http.cache_miss_changed", "proxy.process.http.cache_miss_client_no_cache",
    "proxy.process.http.cache_miss_ims", "proxy.process.http.cache_miss_client_not_cacheable"}},
  // Total requests, both hits and misses (this is slightly superfluous, but assures correct percentage calculations)
  {"proxy.process.cache_total_requests", RECD_COUNTER, {"proxy.process.cache_total_hits", "proxy.process.cache_total_misses"}},
  // Total cache requests bytes which are cache hits
  {"proxy.process.cache_total_hits_bytes",
   RECD_INT,
   {"proxy.process.http.tcp_hit_user_agent_bytes_stat", "proxy.process.http.tcp_refresh_hit_user_agent_bytes_stat",
    "proxy.process.http.tcp_ims_hit_user_agent_bytes_stat"}},
  // Total cache requests bytes which are cache misses
  {"proxy.process.cache_total_misses_bytes",
   RECD_INT,
   {"proxy.process.http.tcp_miss_user_agent_bytes_stat", "proxy.process.http.tcp_expired_miss_user_agent_bytes_stat",
    "proxy.process.http.tcp_refresh_miss_user_agent_bytes_stat", "proxy.process.http.tcp_ims_miss_user_agent_bytes_stat"}},
  // Total request bytes, both hits and misses
  {"proxy.process.cache_total_bytes", RECD_INT, {"proxy.process.cache_total_hits_bytes", "proxy.process.cache_total_misses_bytes"}},
  // Total of all server connections (sum of origins and parent connections)
  {"proxy.process.current_server_connections",
   RECD_INT,
   {"proxy.process.http.current_server_connections", "proxy.process.http.current_parent_proxy_connections"}}};

// The constructor is responsible for registering the new metrics. ToDo: At some point we could
// in theory expand this to support some sort of configuration, and then replace the hardcoded metrics
// here with parameters to an Add() method.
DerivativeMetrics::DerivativeMetrics()
{
  // Add all the sum derived metrics to LibRecords
  for (auto &&[derived_metric, type, metric_parts] : sum_metrics) {
    (void)metric_parts;

    switch (type) {
    case RECD_INT:
      RecRegisterStatInt(RECT_PROCESS, derived_metric, static_cast<RecInt>(0), RECP_NON_PERSISTENT);
      break;
    case RECD_COUNTER:
      RecRegisterStatCounter(RECT_PROCESS, derived_metric, static_cast<RecCounter>(0), RECP_NON_PERSISTENT);
      break;
    default:
      ink_release_assert(!"Unsupported metric type");
      break;
    }
  }
}

// Updates all the derived metrics
void
DerivativeMetrics::Update()
{
  int error = REC_ERR_FAIL;
  RecData sum;
  RecInt int_val;
  RecCounter counter_val;

  for (auto &&[derived_metric, type, metric_parts] : sum_metrics) {
    ink_zero(sum);
    for (auto &&metric : metric_parts) {
      switch (type) {
      case RECD_INT:
        error = RecGetRecordInt(metric, &int_val);
        sum.rec_int += int_val;
        break;
      case RECD_COUNTER:
        error = RecGetRecordCounter(metric, &counter_val);
        sum.rec_counter += counter_val;
        break;
      default:
        ink_release_assert(!"Unsupported metric type");
        break;
      }
      if (error) { // No point in continuing here, since the metric is failing for odd reasons
        break;
      }
    }

    if (!error) {
      RecSetRecord(RECT_NULL, derived_metric, type, &sum, nullptr, REC_SOURCE_EXPLICIT);
    }
  }
}
