// Copyright 2020 The Fuchsia 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 <optional>

#include <fbl/algorithm.h>

#include "ram-info.h"

namespace ram_metrics = ::llcpp::fuchsia::hardware::ram::metrics;

static constexpr char kVersionString[] = "1";

static void PrintUsage(const char* cmd) {
  fprintf(stderr, "\nQuery RAM bandwith\n");
  fprintf(stderr, "\t%s             Print default domain values\n", cmd);
  fprintf(stderr, "\t%s --help      Print this message and quit.\n", cmd);
  fprintf(stderr, "\t%s --version   Print version and quit.\n", cmd);
  fprintf(stderr, "\t%s --windowing Print windowing tool result and quit.\n", cmd);
  fprintf(stderr, "\t%s --csv       Print RAM bandwidth in CSV format.\n", cmd);
  fprintf(stderr, "\t%s --channels|-c <channel0[,channel1,...]>\n", cmd);
  fprintf(stderr, "\t\t Use the specified port masks instead of the device defaults.\n");
  fprintf(stderr, "\t\t For example: %s --channels 0x17,0xc,16.\n", cmd);
  fprintf(stderr, "\t%s --cycles-to-measure|-m <cycles>\n", cmd);
  fprintf(stderr, "\t\t Use the specified cycles to measure instead of the device default.\n");
  fprintf(stderr, "\t\t For example: %s --cycles-to-measure 39600000.\n", cmd);
}

int main(int argc, char* argv[]) {
  bool use_csv = false;
  std::optional<std::array<uint64_t, ram_metrics::MAX_COUNT_CHANNELS>> channels = {};
  std::optional<uint64_t> cycles_to_measure = {};

  for (int i = 1; i < argc; i++) {
    if (strcmp(argv[i], "--help") == 0) {
      PrintUsage(argv[0]);
      return 0;
    }
    if (strcmp(argv[i], "--version") == 0) {
      printf("%s\n", kVersionString);
      return 0;
    }
    if (strcmp(argv[i], "--windowing") == 0) {
      auto [channel, device_info] = ram_info::ConnectToRamDevice();
      if (!channel.is_valid()) {
        fprintf(stderr, "unable to connect to ram device, the target might not be supported\n");
        return 1;
      }

      zx_status_t status = ram_info::GetDdrWindowingResults(std::move(channel));
      if (status != ZX_OK) {
        fprintf(stderr, "failed to read windowing tool result: %d\n", status);
        return -1;
      }
      return 0;
    }

    if (strcmp(argv[i], "--csv") == 0) {
      use_csv = true;
    } else if (strcmp(argv[i], "--channels") == 0 || strcmp(argv[i], "-c") == 0) {
      if (i == argc - 1) {
        PrintUsage(argv[0]);
        return 1;
      }

      auto result = ram_info::ParseChannelString(argv[++i]);
      if (result.is_error()) {
        PrintUsage(argv[0]);
        return 1;
      }

      channels.emplace(result.value());
    } else if (strcmp(argv[i], "--cycles-to-measure") == 0 || strcmp(argv[i], "-m") == 0) {
      if (i == argc - 1) {
        PrintUsage(argv[0]);
        return 1;
      }

      cycles_to_measure = strtoul(argv[++i], NULL, 0);
    } else {
      PrintUsage(argv[0]);
      return 1;
    }
  }

  auto [channel, device_info] = ram_info::ConnectToRamDevice();
  if (!channel.is_valid()) {
    fprintf(stderr, "unable to connect to ram device, the target might not be supported\n");
    return 1;
  }

  ::llcpp::fuchsia::hardware::ram::metrics::BandwidthMeasurementConfig config = {};
  config.cycles_to_measure =
      cycles_to_measure ? *cycles_to_measure : device_info.default_cycles_to_measure;

  ram_info::DefaultPrinter default_printer(stdout, config.cycles_to_measure);
  ram_info::CsvPrinter csv_printer(stdout, config.cycles_to_measure);

  ram_info::Printer* printer = &default_printer;
  if (use_csv) {
    printer = &csv_printer;
  }

  if (channels) {
    for (size_t i = 0; i < channels->size(); i++) {
      printer->AddChannelName(i, "channel " + std::to_string(i));
      config.channels[i] = channels->at(i);
    }
  } else {
    for (size_t i = 0; i < std::size(device_info.default_channels); i++) {
      if (device_info.default_channels[i].name == nullptr) {
        break;
      }

      printer->AddChannelName(i, device_info.default_channels[i].name);
      config.channels[i] = device_info.default_channels[i].mask;
    }
  }

  zx_status_t status = MeasureBandwith(printer, std::move(channel), config);
  if (status != ZX_OK) {
    fprintf(stderr, "failed to measure bandwidth: %d\n", status);
    return -1;
  }

  return 0;
}
