/*
 *
 * Copyright 2018 gRPC authors.
 *
 * 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.
 *
 */

#include <grpc/support/port_platform.h>

#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h"

#include <grpc/support/atm.h>
#include <grpc/support/string_util.h>
#include <string.h>

namespace grpc_core {

void XdsLbClientStats::AddCallStarted() {
  gpr_atm_full_fetch_add(&num_calls_started_, (gpr_atm)1);
}

void XdsLbClientStats::AddCallFinished(bool finished_with_client_failed_to_send,
                                       bool finished_known_received) {
  gpr_atm_full_fetch_add(&num_calls_finished_, (gpr_atm)1);
  if (finished_with_client_failed_to_send) {
    gpr_atm_full_fetch_add(&num_calls_finished_with_client_failed_to_send_,
                           (gpr_atm)1);
  }
  if (finished_known_received) {
    gpr_atm_full_fetch_add(&num_calls_finished_known_received_, (gpr_atm)1);
  }
}

void XdsLbClientStats::AddCallDroppedLocked(char* token) {
  // Increment num_calls_started and num_calls_finished.
  gpr_atm_full_fetch_add(&num_calls_started_, (gpr_atm)1);
  gpr_atm_full_fetch_add(&num_calls_finished_, (gpr_atm)1);
  // Record the drop.
  if (drop_token_counts_ == nullptr) {
    drop_token_counts_.reset(New<DroppedCallCounts>());
  }
  for (size_t i = 0; i < drop_token_counts_->size(); ++i) {
    if (strcmp((*drop_token_counts_)[i].token.get(), token) == 0) {
      ++(*drop_token_counts_)[i].count;
      return;
    }
  }
  // Not found, so add a new entry.
  drop_token_counts_->emplace_back(UniquePtr<char>(gpr_strdup(token)), 1);
}

namespace {

void AtomicGetAndResetCounter(int64_t* value, gpr_atm* counter) {
  *value = static_cast<int64_t>(gpr_atm_full_xchg(counter, (gpr_atm)0));
}

}  // namespace

void XdsLbClientStats::GetLocked(
    int64_t* num_calls_started, int64_t* num_calls_finished,
    int64_t* num_calls_finished_with_client_failed_to_send,
    int64_t* num_calls_finished_known_received,
    UniquePtr<DroppedCallCounts>* drop_token_counts) {
  AtomicGetAndResetCounter(num_calls_started, &num_calls_started_);
  AtomicGetAndResetCounter(num_calls_finished, &num_calls_finished_);
  AtomicGetAndResetCounter(num_calls_finished_with_client_failed_to_send,
                           &num_calls_finished_with_client_failed_to_send_);
  AtomicGetAndResetCounter(num_calls_finished_known_received,
                           &num_calls_finished_known_received_);
  *drop_token_counts = std::move(drop_token_counts_);
}

}  // namespace grpc_core
