// Copyright (c) 2011 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 <cstdio>
#include <cstdlib>

#include "metrics/metrics_library.h"

namespace {

enum Mode {
  kModeSendSample,
  kModeSendEnumSample,
  kModeSendSparseSample,
  kModeSendUserAction,
  kModeSendCrosEvent,
  kModeHasConsent,
  kModeIsGuestMode,
  kModeShowConsentId,
  kModeCreateConsent,
  kModeDeleteConsent,
  kModeReplayFile,
};

void ShowUsage() {
  fprintf(
      stderr,
      "Usage:  metrics_client [-W <file>] [-t] name sample min max nbuckets\n"
      "        metrics_client [-W <file>] -e   name sample max\n"
      "        metrics_client [-W <file>] -s   name sample\n"
      "        metrics_client [-W <file>] -v   event\n"
      "        metrics_client [-W <file>] -u action\n"
      "        metrics_client [-W <file>] -R <file>\n"
      "        metrics_client [-cCDg]\n"
      "\n"
      "  default: send an integer-valued histogram sample\n"
      "           |min| > 0, |min| <= sample < |max|\n"
      "  -C: Create consent file such that -c will return 0.\n"
      "  -D: Delete consent file such that -c will return 1.\n"
      "  -R <file>: Replay events from a file.\n"
      "  -W <file>: Write events to a file.\n"
      "  -c: return exit status 0 if user consents to stats, 1 otherwise,\n"
      "      in guest mode always return 1\n"
      "  -e: send linear/enumeration histogram data\n"
      "  -g: return exit status 0 if machine in guest mode, 1 otherwise\n"
      // The -i flag prints the client ID, if it exists and is valid.
      // It is not advertised here because it is deprecated and for internal
      // use only (at least by the log tool in debugd).
      "  -s: send a sparse histogram sample\n"
      "  -t: convert sample from double seconds to int milliseconds\n"
      "  -u: send a user action\n"
      "  -v: send a Platform.CrOSEvent enum histogram sample\n");
  exit(1);
}

int ParseInt(const char* arg) {
  char* endptr;
  int value = strtol(arg, &endptr, 0);
  if (*endptr != '\0') {
    fprintf(stderr, "metrics client: bad integer \"%s\"\n", arg);
    ShowUsage();
  }
  return value;
}

double ParseDouble(const char* arg) {
  char* endptr;
  double value = strtod(arg, &endptr);
  if (*endptr != '\0') {
    fprintf(stderr, "metrics client: bad double \"%s\"\n", arg);
    ShowUsage();
  }
  return value;
}

int SendStats(char* argv[],
              int name_index,
              enum Mode mode,
              bool secs_to_msecs,
              const char* output_file) {
  const char* name = argv[name_index];
  int sample;
  if (secs_to_msecs) {
    sample = static_cast<int>(ParseDouble(argv[name_index + 1]) * 1000.0);
  } else {
    sample = ParseInt(argv[name_index + 1]);
  }

  MetricsLibrary metrics_lib;
  metrics_lib.Init();
  if (output_file) {
    metrics_lib.SetOutputFile(output_file);
  }
  if (mode == kModeSendSparseSample) {
    metrics_lib.SendSparseToUMA(name, sample);
  } else if (mode == kModeSendEnumSample) {
    int max = ParseInt(argv[name_index + 2]);
    metrics_lib.SendEnumToUMA(name, sample, max);
  } else {
    int min = ParseInt(argv[name_index + 2]);
    int max = ParseInt(argv[name_index + 3]);
    int nbuckets = ParseInt(argv[name_index + 4]);
    metrics_lib.SendToUMA(name, sample, min, max, nbuckets);
  }
  return 0;
}

int SendUserAction(char* argv[], int action_index) {
  const char* action = argv[action_index];
  MetricsLibrary metrics_lib;
  metrics_lib.Init();
  metrics_lib.SendUserActionToUMA(action);
  return 0;
}

int SendCrosEvent(char* argv[], int action_index) {
  const char* event = argv[action_index];
  bool result;
  MetricsLibrary metrics_lib;
  metrics_lib.Init();
  result = metrics_lib.SendCrosEventToUMA(event);
  if (!result) {
    fprintf(stderr, "metrics_client: could not send event %s\n", event);
    return 1;
  }
  return 0;
}

int CreateConsent() {
  MetricsLibrary metrics_lib;
  metrics_lib.Init();
  return metrics_lib.EnableMetrics() ? 0 : 1;
}

int DeleteConsent() {
  MetricsLibrary metrics_lib;
  metrics_lib.Init();
  return metrics_lib.DisableMetrics() ? 0 : 1;
}

int HasConsent() {
  MetricsLibrary metrics_lib;
  metrics_lib.Init();
  return metrics_lib.AreMetricsEnabled() ? 0 : 1;
}

int IsGuestMode() {
  MetricsLibrary metrics_lib;
  metrics_lib.Init();
  return metrics_lib.IsGuestMode() ? 0 : 1;
}

int ShowConsentId() {
  MetricsLibrary metrics_lib;
  metrics_lib.Init();
  std::string id;
  if (metrics_lib.ConsentId(&id) == false) {
    fprintf(stderr, "error: consent not given\n");
    return 1;
  }
  printf("%s\n", id.c_str());
  return 0;
}

int ReplayFile(const char* input_file, const char* output_file) {
  MetricsLibrary metrics_lib;
  metrics_lib.Init();
  if (output_file) {
    metrics_lib.SetOutputFile(output_file);
  }
  return metrics_lib.Replay(input_file) ? 0 : 1;
}

}  // namespace

int main(int argc, char** argv) {
  enum Mode mode = kModeSendSample;
  bool secs_to_msecs = false;
  const char* output_file = nullptr;
  const char* input_file = nullptr;

  // Parse arguments
  int flag;
  while ((flag = getopt(argc, argv, "CDR:W:cegistuv")) != -1) {
    switch (flag) {
      case 'C':
        mode = kModeCreateConsent;
        break;
      case 'D':
        mode = kModeDeleteConsent;
        break;
      case 'R':
        mode = kModeReplayFile;
        input_file = optarg;
        break;
      case 'W':
        output_file = optarg;
        break;
      case 'c':
        mode = kModeHasConsent;
        break;
      case 'e':
        mode = kModeSendEnumSample;
        break;
      case 'g':
        mode = kModeIsGuestMode;
        break;
      case 'i':
        // This flag is slated for removal.
        // See comment in ShowUsage().
        mode = kModeShowConsentId;
        break;
      case 's':
        mode = kModeSendSparseSample;
        break;
      case 't':
        secs_to_msecs = true;
        break;
      case 'u':
        mode = kModeSendUserAction;
        break;
      case 'v':
        mode = kModeSendCrosEvent;
        break;
      default:
        ShowUsage();
        break;
    }
  }
  int arg_index = optind;

  int expected_args = 0;
  if (mode == kModeSendSample)
    expected_args = 5;
  else if (mode == kModeSendEnumSample)
    expected_args = 3;
  else if (mode == kModeSendSparseSample)
    expected_args = 2;
  else if (mode == kModeSendUserAction)
    expected_args = 1;
  else if (mode == kModeSendCrosEvent)
    expected_args = 1;

  if ((arg_index + expected_args) != argc) {
    ShowUsage();
  }

  switch (mode) {
    case kModeSendSample:
    case kModeSendEnumSample:
    case kModeSendSparseSample:
      if ((mode != kModeSendSample) && secs_to_msecs) {
        ShowUsage();
      }
      return SendStats(argv, arg_index, mode, secs_to_msecs, output_file);
    case kModeSendUserAction:
      return SendUserAction(argv, arg_index);
    case kModeSendCrosEvent:
      return SendCrosEvent(argv, arg_index);
    case kModeCreateConsent:
      return CreateConsent();
    case kModeDeleteConsent:
      return DeleteConsent();
    case kModeHasConsent:
      return HasConsent();
    case kModeIsGuestMode:
      return IsGuestMode();
    case kModeShowConsentId:
      return ShowConsentId();
    case kModeReplayFile:
      return ReplayFile(input_file, output_file);
    default:
      ShowUsage();
      return 0;
  }
}
