// 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_library.h"

enum Mode {
    kModeSendSample,
    kModeSendEnumSample,
    kModeSendSparseSample,
    kModeSendUserAction,
    kModeSendCrosEvent,
    kModeHasConsent,
    kModeIsGuestMode,
};

void ShowUsage() {
  fprintf(stderr,
          "Usage:  metrics_client [-ab] [-t] name sample min max nbuckets\n"
          "        metrics_client [-ab] -e   name sample max\n"
          "        metrics_client [-ab] -s   name sample\n"
          "        metrics_client [-ab] -v   event\n"
          "        metrics_client -u action\n"
          "        metrics_client [-cg]\n"
          "\n"
          "  default: send metric with integer values to Chrome only\n"
          "           |min| > 0, |min| <= sample < |max|\n"
          "  -a: send metric (name/sample) to Autotest only\n"
          "  -b: send metric to both Chrome and Autotest\n"
          "  -c: return exit status 0 if user consents to stats, 1 otherwise\n"
          "  -e: send linear/enumeration histogram data\n"
          "  -g: return exit status 0 if machine in guest mode, 1 otherwise\n"
          "  -s: send a sparse histogram sample\n"
          "  -t: convert sample from double seconds to int milliseconds\n"
          "  -u: send a user action to Chrome\n"
          "  -v: send a Platform.CrOSEvent enum histogram sample\n"
          );
  exit(1);
}

static int SendStats(char* argv[],
                     int name_index,
                     enum Mode mode,
                     bool secs_to_msecs,
                     bool send_to_autotest,
                     bool send_to_chrome) {
  const char* name = argv[name_index];
  int sample;
  if (secs_to_msecs) {
    sample = static_cast<int>(atof(argv[name_index + 1]) * 1000.0);
  } else {
    sample = atoi(argv[name_index + 1]);
  }

  // Send metrics
  if (send_to_autotest) {
    MetricsLibrary::SendToAutotest(name, sample);
  }

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

static 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;
}

static 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;
}

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

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

int main(int argc, char** argv) {
  enum Mode mode = kModeSendSample;
  bool send_to_autotest = false;
  bool send_to_chrome = true;
  bool secs_to_msecs = false;

  // Parse arguments
  int flag;
  while ((flag = getopt(argc, argv, "abcegstuv")) != -1) {
    switch (flag) {
      case 'a':
        send_to_autotest = true;
        send_to_chrome = false;
        break;
      case 'b':
        send_to_chrome = true;
        send_to_autotest = true;
        break;
      case 'c':
        mode = kModeHasConsent;
        break;
      case 'e':
        mode = kModeSendEnumSample;
        break;
      case 'g':
        mode = kModeIsGuestMode;
        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,
                       send_to_autotest,
                       send_to_chrome);
    case kModeSendUserAction:
      return SendUserAction(argv, arg_index);
    case kModeSendCrosEvent:
      return SendCrosEvent(argv, arg_index);
    case kModeHasConsent:
      return HasConsent();
    case kModeIsGuestMode:
      return IsGuestMode();
    default:
      ShowUsage();
      return 0;
  }
}
