/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * 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 <cstdio>
#include <cstdlib>

#include <base/memory/scoped_vector.h>

#include "constants.h"
#include "metrics/metrics_library.h"

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

void ShowUsage() {
  fprintf(stderr,
          "Usage:  metrics_client [-t] name sample min max nbuckets\n"
          "        metrics_client -e   name sample max\n"
          "        metrics_client -s   name sample\n"
          "        metrics_client -v   event\n"
          "        metrics_client -u action\n"
          "        metrics_client [-cdg]\n"
          "\n"
          "  default: send metric with integer values \n"
          "           |min| > 0, |min| <= sample < |max|\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"
          "  -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 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;
}

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

static int SendStats(char* argv[],
                     int name_index,
                     enum Mode mode,
                     bool secs_to_msecs) {
  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 (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;
}

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 secs_to_msecs = false;

  // Parse arguments
  int flag;
  while ((flag = getopt(argc, argv, "abcegstuv")) != -1) {
    switch (flag) {
      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);
    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;
  }
}
