// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdlib.h>
#include <iostream>
#include <map>
#include <memory>
#include <string>

#include <base/logging.h>
#include <base/message_loop/message_loop.h>
#include <base/optional.h>
#include <base/time/time.h>
#include <base/values.h>
#include <brillo/flag_helper.h>

#include "diagnostics/telem/telem_connection.h"
#include "diagnostics/telem/telemetry_group_enum.h"
#include "diagnostics/telem/telemetry_item_enum.h"

namespace {

void DisplayStringItem(const base::Value& string_item);
void DisplayIntItem(const base::Value& int_item);
void DisplayListItem(const base::Value& list_item);
bool DisplayTelemetryItem(const base::Value& telem_item);
bool DisplayOptionalTelemetryItem(
    const std::string& item_name,
    const base::Optional<base::Value>& telem_item);

// URI on which the gRPC interface exposed by the diagnosticsd daemon is
// listening. This is the same URI that the diagnosticsd daemon uses to
// communicate with the diagnostics_processor, so this tool should not
// be used when diagnostics_processor is running.
constexpr char kDiagnosticsdGrpcUri[] =
    "unix:/run/diagnostics/grpc_sockets/diagnosticsd_socket";

struct {
  const char* switch_name;
  diagnostics::TelemetryItemEnum telemetry_item;
} kTelemetryItemSwitches[] = {
    {"uptime", diagnostics::TelemetryItemEnum::kUptime},
    {"memtotal", diagnostics::TelemetryItemEnum::kMemTotalMebibytes},
    {"memfree", diagnostics::TelemetryItemEnum::kMemFreeMebibytes},
    {"runnable_entities", diagnostics::TelemetryItemEnum::kNumRunnableEntities},
    {"existing_entities", diagnostics::TelemetryItemEnum::kNumExistingEntities},
    {"idle_time_total", diagnostics::TelemetryItemEnum::kTotalIdleTimeUserHz},
    {"idle_time_per_cpu",
     diagnostics::TelemetryItemEnum::kIdleTimePerCPUUserHz},
    {"button", diagnostics::TelemetryItemEnum::kAcpiButton},
    {"netstat", diagnostics::TelemetryItemEnum::kNetStat},
    {"netdev", diagnostics::TelemetryItemEnum::kNetDev}};

struct {
  const char* switch_name;
  diagnostics::TelemetryGroupEnum telemetry_group;
} kTelemetryGroupSwitches[] = {
    {"disk", diagnostics::TelemetryGroupEnum::kDisk}};

// Helper function to display a base::Value object which has a string
// representation.
void DisplayStringItem(const base::Value& string_item) {
  DCHECK(string_item.is_string());

  std::string val;
  string_item.GetAsString(&val);
  std::cout << val << std::endl;
}

// Helper function to display a base::Value object which has an integer
// representation.
void DisplayIntItem(const base::Value& int_item) {
  DCHECK(int_item.is_int());

  int val;
  int_item.GetAsInteger(&val);
  std::cout << val << std::endl;
}

// Helper function to display a base::Value object which has a list
// representation.
void DisplayListItem(const base::Value& list_item) {
  DCHECK(list_item.is_list());

  const base::ListValue* list;
  list_item.GetAsList(&list);
  const base::Value* item;

  // Print a newline so that the first list value starts on a new line.
  std::cout << std::endl;

  // Print each of the list values.
  for (int i = 0; i < list->GetSize(); i++) {
    list->Get(i, &item);
    DisplayTelemetryItem(*item);
  }
}

// Helper function to display a base::Value object which has an arbitrary
// representation.
bool DisplayTelemetryItem(const base::Value& telem_item) {
  if (telem_item.is_int()) {
    DisplayIntItem(telem_item);
  } else if (telem_item.is_string()) {
    DisplayStringItem(telem_item);
  } else if (telem_item.is_list()) {
    DisplayListItem(telem_item);
  } else {
    LOG(ERROR) << "Invalid format for telemetry item.";
    return false;
  }

  return true;
}

// Displays the telemetry item to the console. Returns
// true iff the item was successfully displayed.
bool DisplayOptionalTelemetryItem(
    const std::string& item_name,
    const base::Optional<base::Value>& telem_item) {
  if (!telem_item) {
    LOG(ERROR) << "No telemetry item received.";
    return false;
  }

  std::cout << item_name << ": ";
  return DisplayTelemetryItem(telem_item.value());
}

}  // namespace

// 'telem' command-line tool:
//
// Test driver for libtelem. Only supports requesting individual telemetry
// items. This program does not exercise the caching functionality of libtelem.
int main(int argc, char** argv) {
  DEFINE_string(item, "", "Telemetry item to retrieve.");
  DEFINE_string(group, "", "Group of telemetry items to retrieve.");
  brillo::FlagHelper::Init(argc, argv, "telem - Device telemetry tool.");

  std::map<std::string, diagnostics::TelemetryItemEnum>
      telemetry_switch_to_item;
  std::map<diagnostics::TelemetryItemEnum, std::string>
      telemetry_item_to_switch;
  for (const auto& item : kTelemetryItemSwitches) {
    telemetry_switch_to_item[item.switch_name] = item.telemetry_item;
    telemetry_item_to_switch[item.telemetry_item] = item.switch_name;
  }

  std::map<std::string, diagnostics::TelemetryGroupEnum>
      telemetry_switch_to_group;
  for (const auto& group : kTelemetryGroupSwitches) {
    telemetry_switch_to_group[group.switch_name] = group.telemetry_group;
  }

  logging::InitLogging(logging::LoggingSettings());

  base::MessageLoopForIO message_loop;

  diagnostics::TelemConnection telem_connection;

  telem_connection.Connect(kDiagnosticsdGrpcUri);

  // Make sure at least one item or group is specified.
  if (FLAGS_item == "" && FLAGS_group == "") {
    LOG(ERROR) << "No item or group specified.";
    return EXIT_FAILURE;
  }
  // Validate the item flag.
  if (FLAGS_item != "") {
    if (!telemetry_switch_to_item.count(FLAGS_item)) {
      LOG(ERROR) << "Invalid item: " << FLAGS_item;
      return EXIT_FAILURE;
    }

    // Retrieve and display the telemetry item.
    const base::Optional<base::Value> telem_item =
        telem_connection.GetItem(telemetry_switch_to_item.at(FLAGS_item),
                                 base::TimeDelta::FromSeconds(0));
    if (!DisplayOptionalTelemetryItem(FLAGS_item, telem_item))
      return EXIT_FAILURE;
  }
  // Validate the group flag.
  if (FLAGS_group != "") {
    if (!telemetry_switch_to_group.count(FLAGS_group)) {
      LOG(ERROR) << "Invalid group: " << FLAGS_group;
      return EXIT_FAILURE;
    }

    // Retrieve and display the telemetry group.
    const std::vector<std::pair<diagnostics::TelemetryItemEnum,
                                const base::Optional<base::Value>>>
        telem_items =
            telem_connection.GetGroup(telemetry_switch_to_group.at(FLAGS_group),
                                      base::TimeDelta::FromSeconds(0));
    for (auto item_pair : telem_items) {
      if (!DisplayOptionalTelemetryItem(
              telemetry_item_to_switch.at(item_pair.first), item_pair.second))
        return EXIT_FAILURE;
    }
  }

  return EXIT_SUCCESS;
}
