/*
 *
 * Copyright 2017 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/impl/codegen/port_platform.h>

#include "src/core/lib/channel/channelz.h"

#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "src/core/lib/channel/channelz_registry.h"
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/slice/b64.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/uri/uri_parser.h"

namespace grpc_core {
namespace channelz {

BaseNode::BaseNode(EntityType type) : type_(type), uuid_(-1) {
  // The registry will set uuid_ under its lock.
  ChannelzRegistry::Register(this);
}

BaseNode::~BaseNode() { ChannelzRegistry::Unregister(uuid_); }

char* BaseNode::RenderJsonString() {
  grpc_json* json = RenderJson();
  GPR_ASSERT(json != nullptr);
  char* json_str = grpc_json_dump_to_string(json, 0);
  grpc_json_destroy(json);
  return json_str;
}

CallCountingHelper::CallCountingHelper() {
  num_cores_ = GPR_MAX(1, gpr_cpu_num_cores());
  per_cpu_counter_data_storage_ = static_cast<AtomicCounterData*>(
      gpr_zalloc(sizeof(AtomicCounterData) * num_cores_));
}

CallCountingHelper::~CallCountingHelper() {
  gpr_free(per_cpu_counter_data_storage_);
}

void CallCountingHelper::RecordCallStarted() {
  gpr_atm_no_barrier_fetch_add(
      &per_cpu_counter_data_storage_[grpc_core::ExecCtx::Get()->starting_cpu()]
           .calls_started,
      static_cast<gpr_atm>(1));
  gpr_atm_no_barrier_store(
      &per_cpu_counter_data_storage_[grpc_core::ExecCtx::Get()->starting_cpu()]
           .last_call_started_millis,
      (gpr_atm)ExecCtx::Get()->Now());
}

void CallCountingHelper::RecordCallFailed() {
  gpr_atm_no_barrier_fetch_add(
      &per_cpu_counter_data_storage_[grpc_core::ExecCtx::Get()->starting_cpu()]
           .calls_failed,
      static_cast<gpr_atm>(1));
}

void CallCountingHelper::RecordCallSucceeded() {
  gpr_atm_no_barrier_fetch_add(
      &per_cpu_counter_data_storage_[grpc_core::ExecCtx::Get()->starting_cpu()]
           .calls_succeeded,
      static_cast<gpr_atm>(1));
}

void CallCountingHelper::CollectData(CounterData* out) {
  for (size_t core = 0; core < num_cores_; ++core) {
    out->calls_started += gpr_atm_no_barrier_load(
        &per_cpu_counter_data_storage_[core].calls_started);
    out->calls_succeeded += gpr_atm_no_barrier_load(
        &per_cpu_counter_data_storage_[core].calls_succeeded);
    out->calls_failed += gpr_atm_no_barrier_load(
        &per_cpu_counter_data_storage_[core].calls_failed);
    gpr_atm last_call = gpr_atm_no_barrier_load(
        &per_cpu_counter_data_storage_[core].last_call_started_millis);
    if (last_call > out->last_call_started_millis) {
      out->last_call_started_millis = last_call;
    }
  }
}

void CallCountingHelper::PopulateCallCounts(grpc_json* json) {
  grpc_json* json_iterator = nullptr;
  CounterData data;
  CollectData(&data);
  if (data.calls_started != 0) {
    json_iterator = grpc_json_add_number_string_child(
        json, json_iterator, "callsStarted", data.calls_started);
  }
  if (data.calls_succeeded != 0) {
    json_iterator = grpc_json_add_number_string_child(
        json, json_iterator, "callsSucceeded", data.calls_succeeded);
  }
  if (data.calls_failed) {
    json_iterator = grpc_json_add_number_string_child(
        json, json_iterator, "callsFailed", data.calls_failed);
  }
  if (data.calls_started != 0) {
    gpr_timespec ts = grpc_millis_to_timespec(data.last_call_started_millis,
                                              GPR_CLOCK_REALTIME);
    json_iterator =
        grpc_json_create_child(json_iterator, json, "lastCallStartedTimestamp",
                               gpr_format_timespec(ts), GRPC_JSON_STRING, true);
  }
}

ChannelNode::ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes,
                         bool is_top_level_channel)
    : BaseNode(is_top_level_channel ? EntityType::kTopLevelChannel
                                    : EntityType::kInternalChannel),
      channel_(channel),
      target_(UniquePtr<char>(grpc_channel_get_target(channel_))),
      trace_(channel_tracer_max_nodes) {}

ChannelNode::~ChannelNode() {}

grpc_json* ChannelNode::RenderJson() {
  // We need to track these three json objects to build our object
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
  grpc_json* json = top_level_json;
  grpc_json* json_iterator = nullptr;
  // create and fill the ref child
  json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr,
                                         GRPC_JSON_OBJECT, false);
  json = json_iterator;
  json_iterator = nullptr;
  json_iterator = grpc_json_add_number_string_child(json, json_iterator,
                                                    "channelId", uuid());
  // reset json iterators to top level object
  json = top_level_json;
  json_iterator = nullptr;
  // create and fill the data child.
  grpc_json* data = grpc_json_create_child(json_iterator, json, "data", nullptr,
                                           GRPC_JSON_OBJECT, false);
  json = data;
  json_iterator = nullptr;
  // template method. Child classes may override this to add their specific
  // functionality.
  PopulateConnectivityState(json);
  // populate the target.
  GPR_ASSERT(target_.get() != nullptr);
  grpc_json_create_child(nullptr, json, "target", target_.get(),
                         GRPC_JSON_STRING, false);
  // fill in the channel trace if applicable
  grpc_json* trace_json = trace_.RenderJson();
  if (trace_json != nullptr) {
    trace_json->key = "trace";  // this object is named trace in channelz.proto
    grpc_json_link_child(json, trace_json, nullptr);
  }
  // ask CallCountingHelper to populate trace and call count data.
  call_counter_.PopulateCallCounts(json);
  json = top_level_json;
  // template method. Child classes may override this to add their specific
  // functionality.
  PopulateChildRefs(json);
  return top_level_json;
}

RefCountedPtr<ChannelNode> ChannelNode::MakeChannelNode(
    grpc_channel* channel, size_t channel_tracer_max_nodes,
    bool is_top_level_channel) {
  return MakeRefCounted<grpc_core::channelz::ChannelNode>(
      channel, channel_tracer_max_nodes, is_top_level_channel);
}

ServerNode::ServerNode(grpc_server* server, size_t channel_tracer_max_nodes)
    : BaseNode(EntityType::kServer),
      server_(server),
      trace_(channel_tracer_max_nodes) {}

ServerNode::~ServerNode() {}

char* ServerNode::RenderServerSockets(intptr_t start_socket_id,
                                      intptr_t max_results) {
  // if user does not set max_results, we choose 500.
  size_t pagination_limit = max_results == 0 ? 500 : max_results;
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
  grpc_json* json = top_level_json;
  grpc_json* json_iterator = nullptr;
  ChildSocketsList socket_refs;
  grpc_server_populate_server_sockets(server_, &socket_refs, start_socket_id);
  // declared early so it can be used outside of the loop.
  size_t i = 0;
  if (!socket_refs.empty()) {
    // create list of socket refs
    grpc_json* array_parent = grpc_json_create_child(
        nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false);
    for (i = 0; i < GPR_MIN(socket_refs.size(), pagination_limit); ++i) {
      grpc_json* socket_ref_json = grpc_json_create_child(
          nullptr, array_parent, nullptr, nullptr, GRPC_JSON_OBJECT, false);
      json_iterator = grpc_json_add_number_string_child(
          socket_ref_json, nullptr, "socketId", socket_refs[i]->uuid());
      grpc_json_create_child(json_iterator, socket_ref_json, "name",
                             socket_refs[i]->remote(), GRPC_JSON_STRING, false);
    }
  }
  if (i == socket_refs.size()) {
    json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr,
                                           GRPC_JSON_TRUE, false);
  }
  char* json_str = grpc_json_dump_to_string(top_level_json, 0);
  grpc_json_destroy(top_level_json);
  return json_str;
}

grpc_json* ServerNode::RenderJson() {
  // We need to track these three json objects to build our object
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
  grpc_json* json = top_level_json;
  grpc_json* json_iterator = nullptr;
  // create and fill the ref child
  json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr,
                                         GRPC_JSON_OBJECT, false);
  json = json_iterator;
  json_iterator = nullptr;
  json_iterator = grpc_json_add_number_string_child(json, json_iterator,
                                                    "serverId", uuid());
  // reset json iterators to top level object
  json = top_level_json;
  json_iterator = nullptr;
  // create and fill the data child.
  grpc_json* data = grpc_json_create_child(json_iterator, json, "data", nullptr,
                                           GRPC_JSON_OBJECT, false);
  json = data;
  json_iterator = nullptr;
  // fill in the channel trace if applicable
  grpc_json* trace_json = trace_.RenderJson();
  if (trace_json != nullptr) {
    trace_json->key = "trace";  // this object is named trace in channelz.proto
    grpc_json_link_child(json, trace_json, nullptr);
  }
  // ask CallCountingHelper to populate trace and call count data.
  call_counter_.PopulateCallCounts(json);
  json = top_level_json;
  ChildRefsList listen_sockets;
  grpc_server_populate_listen_sockets(server_, &listen_sockets);
  if (!listen_sockets.empty()) {
    grpc_json* array_parent = grpc_json_create_child(
        nullptr, json, "listenSocket", nullptr, GRPC_JSON_ARRAY, false);
    for (size_t i = 0; i < listen_sockets.size(); ++i) {
      json_iterator =
          grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr,
                                 GRPC_JSON_OBJECT, false);
      grpc_json_add_number_string_child(json_iterator, nullptr, "socketId",
                                        listen_sockets[i]);
    }
  }
  return top_level_json;
}

static void PopulateSocketAddressJson(grpc_json* json, const char* name,
                                      const char* addr_str) {
  if (addr_str == nullptr) return;
  grpc_json* json_iterator = nullptr;
  json_iterator = grpc_json_create_child(json_iterator, json, name, nullptr,
                                         GRPC_JSON_OBJECT, false);
  json = json_iterator;
  json_iterator = nullptr;
  grpc_uri* uri = grpc_uri_parse(addr_str, true);
  if ((uri != nullptr) && ((strcmp(uri->scheme, "ipv4") == 0) ||
                           (strcmp(uri->scheme, "ipv6") == 0))) {
    const char* host_port = uri->path;
    if (*host_port == '/') ++host_port;
    char* host = nullptr;
    char* port = nullptr;
    GPR_ASSERT(gpr_split_host_port(host_port, &host, &port));
    int port_num = -1;
    if (port != nullptr) {
      port_num = atoi(port);
    }
    char* b64_host = grpc_base64_encode(host, strlen(host), false, false);
    json_iterator = grpc_json_create_child(json_iterator, json, "tcpip_address",
                                           nullptr, GRPC_JSON_OBJECT, false);
    json = json_iterator;
    json_iterator = nullptr;
    json_iterator = grpc_json_add_number_string_child(json, json_iterator,
                                                      "port", port_num);
    json_iterator = grpc_json_create_child(json_iterator, json, "ip_address",
                                           b64_host, GRPC_JSON_STRING, true);
    gpr_free(host);
    gpr_free(port);

  } else if (uri != nullptr && strcmp(uri->scheme, "unix") == 0) {
    json_iterator = grpc_json_create_child(json_iterator, json, "uds_address",
                                           nullptr, GRPC_JSON_OBJECT, false);
    json = json_iterator;
    json_iterator = nullptr;
    json_iterator =
        grpc_json_create_child(json_iterator, json, "filename",
                               gpr_strdup(uri->path), GRPC_JSON_STRING, true);
  } else {
    json_iterator = grpc_json_create_child(json_iterator, json, "other_address",
                                           nullptr, GRPC_JSON_OBJECT, false);
    json = json_iterator;
    json_iterator = nullptr;
    json_iterator = grpc_json_create_child(json_iterator, json, "name",
                                           addr_str, GRPC_JSON_STRING, false);
  }
  grpc_uri_destroy(uri);
}

SocketNode::SocketNode(UniquePtr<char> local, UniquePtr<char> remote)
    : BaseNode(EntityType::kSocket),
      local_(std::move(local)),
      remote_(std::move(remote)) {}

void SocketNode::RecordStreamStartedFromLocal() {
  gpr_atm_no_barrier_fetch_add(&streams_started_, static_cast<gpr_atm>(1));
  gpr_atm_no_barrier_store(&last_local_stream_created_millis_,
                           (gpr_atm)ExecCtx::Get()->Now());
}

void SocketNode::RecordStreamStartedFromRemote() {
  gpr_atm_no_barrier_fetch_add(&streams_started_, static_cast<gpr_atm>(1));
  gpr_atm_no_barrier_store(&last_remote_stream_created_millis_,
                           (gpr_atm)ExecCtx::Get()->Now());
}

void SocketNode::RecordMessagesSent(uint32_t num_sent) {
  gpr_atm_no_barrier_fetch_add(&messages_sent_, static_cast<gpr_atm>(num_sent));
  gpr_atm_no_barrier_store(&last_message_sent_millis_,
                           (gpr_atm)ExecCtx::Get()->Now());
}

void SocketNode::RecordMessageReceived() {
  gpr_atm_no_barrier_fetch_add(&messages_received_, static_cast<gpr_atm>(1));
  gpr_atm_no_barrier_store(&last_message_received_millis_,
                           (gpr_atm)ExecCtx::Get()->Now());
}

grpc_json* SocketNode::RenderJson() {
  // We need to track these three json objects to build our object
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
  grpc_json* json = top_level_json;
  grpc_json* json_iterator = nullptr;
  // create and fill the ref child
  json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr,
                                         GRPC_JSON_OBJECT, false);
  json = json_iterator;
  json_iterator = nullptr;
  json_iterator = grpc_json_add_number_string_child(json, json_iterator,
                                                    "socketId", uuid());
  json = top_level_json;
  PopulateSocketAddressJson(json, "remote", remote_.get());
  PopulateSocketAddressJson(json, "local", local_.get());
  // reset json iterators to top level object
  json = top_level_json;
  json_iterator = nullptr;
  // create and fill the data child.
  grpc_json* data = grpc_json_create_child(json_iterator, json, "data", nullptr,
                                           GRPC_JSON_OBJECT, false);
  json = data;
  json_iterator = nullptr;
  gpr_timespec ts;
  if (streams_started_ != 0) {
    json_iterator = grpc_json_add_number_string_child(
        json, json_iterator, "streamsStarted", streams_started_);
    if (last_local_stream_created_millis_ != 0) {
      ts = grpc_millis_to_timespec(last_local_stream_created_millis_,
                                   GPR_CLOCK_REALTIME);
      json_iterator = grpc_json_create_child(
          json_iterator, json, "lastLocalStreamCreatedTimestamp",
          gpr_format_timespec(ts), GRPC_JSON_STRING, true);
    }
    if (last_remote_stream_created_millis_ != 0) {
      ts = grpc_millis_to_timespec(last_remote_stream_created_millis_,
                                   GPR_CLOCK_REALTIME);
      json_iterator = grpc_json_create_child(
          json_iterator, json, "lastRemoteStreamCreatedTimestamp",
          gpr_format_timespec(ts), GRPC_JSON_STRING, true);
    }
  }
  if (streams_succeeded_ != 0) {
    json_iterator = grpc_json_add_number_string_child(
        json, json_iterator, "streamsSucceeded", streams_succeeded_);
  }
  if (streams_failed_) {
    json_iterator = grpc_json_add_number_string_child(
        json, json_iterator, "streamsFailed", streams_failed_);
  }
  if (messages_sent_ != 0) {
    json_iterator = grpc_json_add_number_string_child(
        json, json_iterator, "messagesSent", messages_sent_);
    ts = grpc_millis_to_timespec(last_message_sent_millis_, GPR_CLOCK_REALTIME);
    json_iterator =
        grpc_json_create_child(json_iterator, json, "lastMessageSentTimestamp",
                               gpr_format_timespec(ts), GRPC_JSON_STRING, true);
  }
  if (messages_received_ != 0) {
    json_iterator = grpc_json_add_number_string_child(
        json, json_iterator, "messagesReceived", messages_received_);
    ts = grpc_millis_to_timespec(last_message_received_millis_,
                                 GPR_CLOCK_REALTIME);
    json_iterator = grpc_json_create_child(
        json_iterator, json, "lastMessageReceivedTimestamp",
        gpr_format_timespec(ts), GRPC_JSON_STRING, true);
  }
  if (keepalives_sent_ != 0) {
    json_iterator = grpc_json_add_number_string_child(
        json, json_iterator, "keepAlivesSent", keepalives_sent_);
  }
  return top_level_json;
}

ListenSocketNode::ListenSocketNode(UniquePtr<char> local_addr)
    : BaseNode(EntityType::kSocket), local_addr_(std::move(local_addr)) {}

grpc_json* ListenSocketNode::RenderJson() {
  // We need to track these three json objects to build our object
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
  grpc_json* json = top_level_json;
  grpc_json* json_iterator = nullptr;
  // create and fill the ref child
  json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr,
                                         GRPC_JSON_OBJECT, false);
  json = json_iterator;
  json_iterator = nullptr;
  json_iterator = grpc_json_add_number_string_child(json, json_iterator,
                                                    "socketId", uuid());
  json = top_level_json;
  PopulateSocketAddressJson(json, "local", local_addr_.get());

  return top_level_json;
}

}  // namespace channelz
}  // namespace grpc_core
