/*
 * 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.
 */
#ifndef ART_CMDLINE_CMDLINE_TYPES_H_
#define ART_CMDLINE_CMDLINE_TYPES_H_

#define CMDLINE_NDEBUG 1  // Do not output any debugging information for parsing.

#include "cmdline/memory_representation.h"
#include "cmdline/detail/cmdline_debug_detail.h"
#include "cmdline_type_parser.h"

// Includes for the types that are being specialized
#include <string>
#include "unit.h"
#include "jdwp/jdwp.h"
#include "runtime/base/logging.h"
#include "gc/collector_type.h"
#include "gc/space/large_object_space.h"
#include "profiler_options.h"

namespace art {

// The default specialization will always fail parsing the type from a string.
// Provide your own specialization that inherits from CmdlineTypeParser<T>
// and implements either Parse or ParseAndAppend
// (only if the argument was defined with ::AppendValues()) but not both.
template <typename T>
struct CmdlineType : CmdlineTypeParser<T> {
};

// Specializations for CmdlineType<T> follow:

// Parse argument definitions for Unit-typed arguments.
template <>
struct CmdlineType<Unit> : CmdlineTypeParser<Unit> {
  Result Parse(const std::string& args) {
    if (args == "") {
      return Result::Success(Unit{});  // NOLINT [whitespace/braces] [5]
    }
    return Result::Failure("Unexpected extra characters " + args);
  }
};

template <>
struct CmdlineType<JDWP::JdwpOptions> : CmdlineTypeParser<JDWP::JdwpOptions> {
  /*
   * Handle one of the JDWP name/value pairs.
   *
   * JDWP options are:
   *  help: if specified, show help message and bail
   *  transport: may be dt_socket or dt_shmem
   *  address: for dt_socket, "host:port", or just "port" when listening
   *  server: if "y", wait for debugger to attach; if "n", attach to debugger
   *  timeout: how long to wait for debugger to connect / listen
   *
   * Useful with server=n (these aren't supported yet):
   *  onthrow=<exception-name>: connect to debugger when exception thrown
   *  onuncaught=y|n: connect to debugger when uncaught exception thrown
   *  launch=<command-line>: launch the debugger itself
   *
   * The "transport" option is required, as is "address" if server=n.
   */
  Result Parse(const std::string& options) {
    VLOG(jdwp) << "ParseJdwpOptions: " << options;

    if (options == "help") {
      return Result::Usage(
          "Example: -Xrunjdwp:transport=dt_socket,address=8000,server=y\n"
          "Example: -Xrunjdwp:transport=dt_socket,address=localhost:6500,server=n\n");
    }

    const std::string s;

    std::vector<std::string> pairs;
    Split(options, ',', &pairs);

    JDWP::JdwpOptions jdwp_options;

    for (const std::string& jdwp_option : pairs) {
      std::string::size_type equals_pos = jdwp_option.find('=');
      if (equals_pos == std::string::npos) {
        return Result::Failure(s +
            "Can't parse JDWP option '" + jdwp_option + "' in '" + options + "'");
      }

      Result parse_attempt = ParseJdwpOption(jdwp_option.substr(0, equals_pos),
                                             jdwp_option.substr(equals_pos + 1),
                                             &jdwp_options);
      if (parse_attempt.IsError()) {
        // We fail to parse this JDWP option.
        return parse_attempt;
      }
    }

    if (jdwp_options.transport == JDWP::kJdwpTransportUnknown) {
      return Result::Failure(s + "Must specify JDWP transport: " + options);
    }
    if (!jdwp_options.server && (jdwp_options.host.empty() || jdwp_options.port == 0)) {
      return Result::Failure(s + "Must specify JDWP host and port when server=n: " + options);
    }

    return Result::Success(std::move(jdwp_options));
  }

  Result ParseJdwpOption(const std::string& name, const std::string& value,
                         JDWP::JdwpOptions* jdwp_options) {
    if (name == "transport") {
      if (value == "dt_socket") {
        jdwp_options->transport = JDWP::kJdwpTransportSocket;
      } else if (value == "dt_android_adb") {
        jdwp_options->transport = JDWP::kJdwpTransportAndroidAdb;
      } else {
        return Result::Failure("JDWP transport not supported: " + value);
      }
    } else if (name == "server") {
      if (value == "n") {
        jdwp_options->server = false;
      } else if (value == "y") {
        jdwp_options->server = true;
      } else {
        return Result::Failure("JDWP option 'server' must be 'y' or 'n'");
      }
    } else if (name == "suspend") {
      if (value == "n") {
        jdwp_options->suspend = false;
      } else if (value == "y") {
        jdwp_options->suspend = true;
      } else {
        return Result::Failure("JDWP option 'suspend' must be 'y' or 'n'");
      }
    } else if (name == "address") {
      /* this is either <port> or <host>:<port> */
      std::string port_string;
      jdwp_options->host.clear();
      std::string::size_type colon = value.find(':');
      if (colon != std::string::npos) {
        jdwp_options->host = value.substr(0, colon);
        port_string = value.substr(colon + 1);
      } else {
        port_string = value;
      }
      if (port_string.empty()) {
        return Result::Failure("JDWP address missing port: " + value);
      }
      char* end;
      uint64_t port = strtoul(port_string.c_str(), &end, 10);
      if (*end != '\0' || port > 0xffff) {
        return Result::Failure("JDWP address has junk in port field: " + value);
      }
      jdwp_options->port = port;
    } else if (name == "launch" || name == "onthrow" || name == "oncaught" || name == "timeout") {
      /* valid but unsupported */
      LOG(INFO) << "Ignoring JDWP option '" << name << "'='" << value << "'";
    } else {
      LOG(INFO) << "Ignoring unrecognized JDWP option '" << name << "'='" << value << "'";
    }

    return Result::SuccessNoValue();
  }

  static const char* Name() { return "JdwpOptions"; }
};

template <size_t Divisor>
struct CmdlineType<Memory<Divisor>> : CmdlineTypeParser<Memory<Divisor>> {
  using typename CmdlineTypeParser<Memory<Divisor>>::Result;

  Result Parse(const std::string arg) {
    CMDLINE_DEBUG_LOG << "Parsing memory: " << arg << std::endl;
    size_t val = ParseMemoryOption(arg.c_str(), Divisor);
    CMDLINE_DEBUG_LOG << "Memory parsed to size_t value: " << val << std::endl;

    if (val == 0) {
      return Result::Failure(std::string("not a valid memory value, or not divisible by ")
                             + std::to_string(Divisor));
    }

    return Result::Success(Memory<Divisor>(val));
  }

  // Parse a string of the form /[0-9]+[kKmMgG]?/, which is used to specify
  // memory sizes.  [kK] indicates kilobytes, [mM] megabytes, and
  // [gG] gigabytes.
  //
  // "s" should point just past the "-Xm?" part of the string.
  // "div" specifies a divisor, e.g. 1024 if the value must be a multiple
  // of 1024.
  //
  // The spec says the -Xmx and -Xms options must be multiples of 1024.  It
  // doesn't say anything about -Xss.
  //
  // Returns 0 (a useless size) if "s" is malformed or specifies a low or
  // non-evenly-divisible value.
  //
  static size_t ParseMemoryOption(const char* s, size_t div) {
    // strtoul accepts a leading [+-], which we don't want,
    // so make sure our string starts with a decimal digit.
    if (isdigit(*s)) {
      char* s2;
      size_t val = strtoul(s, &s2, 10);
      if (s2 != s) {
        // s2 should be pointing just after the number.
        // If this is the end of the string, the user
        // has specified a number of bytes.  Otherwise,
        // there should be exactly one more character
        // that specifies a multiplier.
        if (*s2 != '\0') {
          // The remainder of the string is either a single multiplier
          // character, or nothing to indicate that the value is in
          // bytes.
          char c = *s2++;
          if (*s2 == '\0') {
            size_t mul;
            if (c == '\0') {
              mul = 1;
            } else if (c == 'k' || c == 'K') {
              mul = KB;
            } else if (c == 'm' || c == 'M') {
              mul = MB;
            } else if (c == 'g' || c == 'G') {
              mul = GB;
            } else {
              // Unknown multiplier character.
              return 0;
            }

            if (val <= std::numeric_limits<size_t>::max() / mul) {
              val *= mul;
            } else {
              // Clamp to a multiple of 1024.
              val = std::numeric_limits<size_t>::max() & ~(1024-1);
            }
          } else {
            // There's more than one character after the numeric part.
            return 0;
          }
        }
        // The man page says that a -Xm value must be a multiple of 1024.
        if (val % div == 0) {
          return val;
        }
      }
    }
    return 0;
  }

  static const char* Name() { return Memory<Divisor>::Name(); }
};

template <>
struct CmdlineType<double> : CmdlineTypeParser<double> {
  Result Parse(const std::string& str) {
    char* end = nullptr;
    errno = 0;
    double value = strtod(str.c_str(), &end);

    if (*end != '\0') {
      return Result::Failure("Failed to parse double from " + str);
    }
    if (errno == ERANGE) {
      return Result::OutOfRange(
          "Failed to parse double from " + str + "; overflow/underflow occurred");
    }

    return Result::Success(value);
  }

  static const char* Name() { return "double"; }
};

template <>
struct CmdlineType<unsigned int> : CmdlineTypeParser<unsigned int> {
  Result Parse(const std::string& str) {
    const char* begin = str.c_str();
    char* end;

    // Parse into a larger type (long long) because we can't use strtoul
    // since it silently converts negative values into unsigned long and doesn't set errno.
    errno = 0;
    long long int result = strtoll(begin, &end, 10);  // NOLINT [runtime/int] [4]
    if (begin == end || *end != '\0' || errno == EINVAL) {
      return Result::Failure("Failed to parse integer from " + str);
    } else if ((errno == ERANGE) ||  // NOLINT [runtime/int] [4]
        result < std::numeric_limits<int>::min()
        || result > std::numeric_limits<unsigned int>::max() || result < 0) {
      return Result::OutOfRange(
          "Failed to parse integer from " + str + "; out of unsigned int range");
    }

    return Result::Success(static_cast<unsigned int>(result));
  }

  static const char* Name() { return "unsigned integer"; }
};

// Lightweight nanosecond value type. Allows parser to convert user-input from milliseconds
// to nanoseconds automatically after parsing.
//
// All implicit conversion from uint64_t uses nanoseconds.
struct MillisecondsToNanoseconds {
  // Create from nanoseconds.
  MillisecondsToNanoseconds(uint64_t nanoseconds) : nanoseconds_(nanoseconds) {  // NOLINT [runtime/explicit] [5]
  }

  // Create from milliseconds.
  static MillisecondsToNanoseconds FromMilliseconds(unsigned int milliseconds) {
    return MillisecondsToNanoseconds(MsToNs(milliseconds));
  }

  // Get the underlying nanoseconds value.
  uint64_t GetNanoseconds() const {
    return nanoseconds_;
  }

  // Get the milliseconds value [via a conversion]. Loss of precision will occur.
  uint64_t GetMilliseconds() const {
    return NsToMs(nanoseconds_);
  }

  // Get the underlying nanoseconds value.
  operator uint64_t() const {
    return GetNanoseconds();
  }

  // Default constructors/copy-constructors.
  MillisecondsToNanoseconds() : nanoseconds_(0ul) {}
  MillisecondsToNanoseconds(const MillisecondsToNanoseconds& rhs) = default;
  MillisecondsToNanoseconds(MillisecondsToNanoseconds&& rhs) = default;

 private:
  uint64_t nanoseconds_;
};

template <>
struct CmdlineType<MillisecondsToNanoseconds> : CmdlineTypeParser<MillisecondsToNanoseconds> {
  Result Parse(const std::string& str) {
    CmdlineType<unsigned int> uint_parser;
    CmdlineParseResult<unsigned int> res = uint_parser.Parse(str);

    if (res.IsSuccess()) {
      return Result::Success(MillisecondsToNanoseconds::FromMilliseconds(res.GetValue()));
    } else {
      return Result::CastError(res);
    }
  }

  static const char* Name() { return "MillisecondsToNanoseconds"; }
};

template <>
struct CmdlineType<std::string> : CmdlineTypeParser<std::string> {
  Result Parse(const std::string& args) {
    return Result::Success(args);
  }

  Result ParseAndAppend(const std::string& args,
                        std::string& existing_value) {
    if (existing_value.empty()) {
      existing_value = args;
    } else {
      existing_value += ' ';
      existing_value += args;
    }
    return Result::SuccessNoValue();
  }
};

template <>
struct CmdlineType<std::vector<std::string>> : CmdlineTypeParser<std::vector<std::string>> {
  Result Parse(const std::string& args) {
    assert(false && "Use AppendValues() for a string vector type");
    return Result::Failure("Unconditional failure: string vector must be appended: " + args);
  }

  Result ParseAndAppend(const std::string& args,
                        std::vector<std::string>& existing_value) {
    existing_value.push_back(args);
    return Result::SuccessNoValue();
  }

  static const char* Name() { return "std::vector<std::string>"; }
};

template <char Separator>
struct ParseStringList {
  explicit ParseStringList(std::vector<std::string>&& list) : list_(list) {}

  operator std::vector<std::string>() const {
    return list_;
  }

  operator std::vector<std::string>&&() && {
    return std::move(list_);
  }

  size_t Size() const {
    return list_.size();
  }

  std::string Join() const {
    return art::Join(list_, Separator);
  }

  static ParseStringList<Separator> Split(const std::string& str) {
    std::vector<std::string> list;
    art::Split(str, Separator, &list);
    return ParseStringList<Separator>(std::move(list));
  }

  ParseStringList() = default;
  ParseStringList(const ParseStringList& rhs) = default;
  ParseStringList(ParseStringList&& rhs) = default;

 private:
  std::vector<std::string> list_;
};

template <char Separator>
struct CmdlineType<ParseStringList<Separator>> : CmdlineTypeParser<ParseStringList<Separator>> {
  using Result = CmdlineParseResult<ParseStringList<Separator>>;

  Result Parse(const std::string& args) {
    return Result::Success(ParseStringList<Separator>::Split(args));
  }

  static const char* Name() { return "ParseStringList<Separator>"; }
};

static gc::CollectorType ParseCollectorType(const std::string& option) {
  if (option == "MS" || option == "nonconcurrent") {
    return gc::kCollectorTypeMS;
  } else if (option == "CMS" || option == "concurrent") {
    return gc::kCollectorTypeCMS;
  } else if (option == "SS") {
    return gc::kCollectorTypeSS;
  } else if (option == "GSS") {
    return gc::kCollectorTypeGSS;
  } else if (option == "CC") {
    return gc::kCollectorTypeCC;
  } else if (option == "MC") {
    return gc::kCollectorTypeMC;
  } else {
    return gc::kCollectorTypeNone;
  }
}

struct XGcOption {
  // These defaults are used when the command line arguments for -Xgc:
  // are either omitted completely or partially.
  gc::CollectorType collector_type_ =  kUseReadBarrier ?
                                           // If RB is enabled (currently a build-time decision),
                                           // use CC as the default GC.
                                           gc::kCollectorTypeCC :
                                           gc::kCollectorTypeDefault;
  bool verify_pre_gc_heap_ = false;
  bool verify_pre_sweeping_heap_ = kIsDebugBuild;
  bool verify_post_gc_heap_ = false;
  bool verify_pre_gc_rosalloc_ = kIsDebugBuild;
  bool verify_pre_sweeping_rosalloc_ = false;
  bool verify_post_gc_rosalloc_ = false;
};

template <>
struct CmdlineType<XGcOption> : CmdlineTypeParser<XGcOption> {
  Result Parse(const std::string& option) {  // -Xgc: already stripped
    XGcOption xgc{};  // NOLINT [readability/braces] [4]

    std::vector<std::string> gc_options;
    Split(option, ',', &gc_options);
    for (const std::string& gc_option : gc_options) {
      gc::CollectorType collector_type = ParseCollectorType(gc_option);
      if (collector_type != gc::kCollectorTypeNone) {
        xgc.collector_type_ = collector_type;
      } else if (gc_option == "preverify") {
        xgc.verify_pre_gc_heap_ = true;
      } else if (gc_option == "nopreverify") {
        xgc.verify_pre_gc_heap_ = false;
      }  else if (gc_option == "presweepingverify") {
        xgc.verify_pre_sweeping_heap_ = true;
      } else if (gc_option == "nopresweepingverify") {
        xgc.verify_pre_sweeping_heap_ = false;
      } else if (gc_option == "postverify") {
        xgc.verify_post_gc_heap_ = true;
      } else if (gc_option == "nopostverify") {
        xgc.verify_post_gc_heap_ = false;
      } else if (gc_option == "preverify_rosalloc") {
        xgc.verify_pre_gc_rosalloc_ = true;
      } else if (gc_option == "nopreverify_rosalloc") {
        xgc.verify_pre_gc_rosalloc_ = false;
      } else if (gc_option == "presweepingverify_rosalloc") {
        xgc.verify_pre_sweeping_rosalloc_ = true;
      } else if (gc_option == "nopresweepingverify_rosalloc") {
        xgc.verify_pre_sweeping_rosalloc_ = false;
      } else if (gc_option == "postverify_rosalloc") {
        xgc.verify_post_gc_rosalloc_ = true;
      } else if (gc_option == "nopostverify_rosalloc") {
        xgc.verify_post_gc_rosalloc_ = false;
      } else if ((gc_option == "precise") ||
                 (gc_option == "noprecise") ||
                 (gc_option == "verifycardtable") ||
                 (gc_option == "noverifycardtable")) {
        // Ignored for backwards compatibility.
      } else {
        return Result::Usage(std::string("Unknown -Xgc option ") + gc_option);
      }
    }

    return Result::Success(std::move(xgc));
  }

  static const char* Name() { return "XgcOption"; }
};

struct BackgroundGcOption {
  // If background_collector_type_ is kCollectorTypeNone, it defaults to the
  // XGcOption::collector_type_ after parsing options. If you set this to
  // kCollectorTypeHSpaceCompact then we will do an hspace compaction when
  // we transition to background instead of a normal collector transition.
  gc::CollectorType background_collector_type_;

  BackgroundGcOption(gc::CollectorType background_collector_type)  // NOLINT [runtime/explicit] [5]
    : background_collector_type_(background_collector_type) {}
  BackgroundGcOption()
    : background_collector_type_(gc::kCollectorTypeNone) {

    if (kUseReadBarrier) {
      background_collector_type_ = gc::kCollectorTypeCC;  // Disable background compaction for CC.
    }
  }

  operator gc::CollectorType() const { return background_collector_type_; }
};

template<>
struct CmdlineType<BackgroundGcOption>
  : CmdlineTypeParser<BackgroundGcOption>, private BackgroundGcOption {
  Result Parse(const std::string& substring) {
    // Special handling for HSpaceCompact since this is only valid as a background GC type.
    if (substring == "HSpaceCompact") {
      background_collector_type_ = gc::kCollectorTypeHomogeneousSpaceCompact;
    } else {
      gc::CollectorType collector_type = ParseCollectorType(substring);
      if (collector_type != gc::kCollectorTypeNone) {
        background_collector_type_ = collector_type;
      } else {
        return Result::Failure();
      }
    }

    BackgroundGcOption res = *this;
    return Result::Success(res);
  }

  static const char* Name() { return "BackgroundGcOption"; }
};

template <>
struct CmdlineType<LogVerbosity> : CmdlineTypeParser<LogVerbosity> {
  Result Parse(const std::string& options) {
    LogVerbosity log_verbosity = LogVerbosity();

    std::vector<std::string> verbose_options;
    Split(options, ',', &verbose_options);
    for (size_t j = 0; j < verbose_options.size(); ++j) {
      if (verbose_options[j] == "class") {
        log_verbosity.class_linker = true;
      } else if (verbose_options[j] == "compiler") {
        log_verbosity.compiler = true;
      } else if (verbose_options[j] == "gc") {
        log_verbosity.gc = true;
      } else if (verbose_options[j] == "heap") {
        log_verbosity.heap = true;
      } else if (verbose_options[j] == "jdwp") {
        log_verbosity.jdwp = true;
      } else if (verbose_options[j] == "jni") {
        log_verbosity.jni = true;
      } else if (verbose_options[j] == "monitor") {
        log_verbosity.monitor = true;
      } else if (verbose_options[j] == "profiler") {
        log_verbosity.profiler = true;
      } else if (verbose_options[j] == "signals") {
        log_verbosity.signals = true;
      } else if (verbose_options[j] == "startup") {
        log_verbosity.startup = true;
      } else if (verbose_options[j] == "third-party-jni") {
        log_verbosity.third_party_jni = true;
      } else if (verbose_options[j] == "threads") {
        log_verbosity.threads = true;
      } else if (verbose_options[j] == "verifier") {
        log_verbosity.verifier = true;
      } else {
        return Result::Usage(std::string("Unknown -verbose option ") + verbose_options[j]);
      }
    }

    return Result::Success(log_verbosity);
  }

  static const char* Name() { return "LogVerbosity"; }
};

// TODO: Replace with art::ProfilerOptions for the real thing.
struct TestProfilerOptions {
  // Whether or not the applications should be profiled.
  bool enabled_;
  // Destination file name where the profiling data will be saved into.
  std::string output_file_name_;
  // Generate profile every n seconds.
  uint32_t period_s_;
  // Run profile for n seconds.
  uint32_t duration_s_;
  // Microseconds between samples.
  uint32_t interval_us_;
  // Coefficient to exponential backoff.
  double backoff_coefficient_;
  // Whether the profile should start upon app startup or be delayed by some random offset.
  bool start_immediately_;
  // Top K% of samples that are considered relevant when deciding if the app should be recompiled.
  double top_k_threshold_;
  // How much the top K% samples needs to change in order for the app to be recompiled.
  double top_k_change_threshold_;
  // The type of profile data dumped to the disk.
  ProfileDataType profile_type_;
  // The max depth of the stack collected by the profiler
  uint32_t max_stack_depth_;

  TestProfilerOptions() :
    enabled_(false),
    output_file_name_(),
    period_s_(0),
    duration_s_(0),
    interval_us_(0),
    backoff_coefficient_(0),
    start_immediately_(0),
    top_k_threshold_(0),
    top_k_change_threshold_(0),
    profile_type_(ProfileDataType::kProfilerMethod),
    max_stack_depth_(0) {
  }

  TestProfilerOptions(const TestProfilerOptions& other) = default;
  TestProfilerOptions(TestProfilerOptions&& other) = default;
};

static inline std::ostream& operator<<(std::ostream& stream, const TestProfilerOptions& options) {
  stream << "TestProfilerOptions {" << std::endl;

#define PRINT_TO_STREAM(field) \
  stream << #field << ": '" << options.field << "'" << std::endl;

  PRINT_TO_STREAM(enabled_);
  PRINT_TO_STREAM(output_file_name_);
  PRINT_TO_STREAM(period_s_);
  PRINT_TO_STREAM(duration_s_);
  PRINT_TO_STREAM(interval_us_);
  PRINT_TO_STREAM(backoff_coefficient_);
  PRINT_TO_STREAM(start_immediately_);
  PRINT_TO_STREAM(top_k_threshold_);
  PRINT_TO_STREAM(top_k_change_threshold_);
  PRINT_TO_STREAM(profile_type_);
  PRINT_TO_STREAM(max_stack_depth_);

  stream << "}";

  return stream;
#undef PRINT_TO_STREAM
}

template <>
struct CmdlineType<TestProfilerOptions> : CmdlineTypeParser<TestProfilerOptions> {
  using Result = CmdlineParseResult<TestProfilerOptions>;

 private:
  using StringResult = CmdlineParseResult<std::string>;
  using DoubleResult = CmdlineParseResult<double>;

  template <typename T>
  static Result ParseInto(TestProfilerOptions& options,
                          T TestProfilerOptions::*pField,
                          CmdlineParseResult<T>&& result) {
    assert(pField != nullptr);

    if (result.IsSuccess()) {
      options.*pField = result.ReleaseValue();
      return Result::SuccessNoValue();
    }

    return Result::CastError(result);
  }

  template <typename T>
  static Result ParseIntoRangeCheck(TestProfilerOptions& options,
                                    T TestProfilerOptions::*pField,
                                    CmdlineParseResult<T>&& result,
                                    T min,
                                    T max) {
    if (result.IsSuccess()) {
      const T& value = result.GetValue();

      if (value < min || value > max) {
        CmdlineParseResult<T> out_of_range = CmdlineParseResult<T>::OutOfRange(value, min, max);
        return Result::CastError(out_of_range);
      }
    }

    return ParseInto(options, pField, std::forward<CmdlineParseResult<T>>(result));
  }

  static StringResult ParseStringAfterChar(const std::string& s, char c) {
    std::string parsed_value;

    std::string::size_type colon = s.find(c);
    if (colon == std::string::npos) {
      return StringResult::Usage(std::string() + "Missing char " + c + " in option " + s);
    }
    // Add one to remove the char we were trimming until.
    parsed_value = s.substr(colon + 1);
    return StringResult::Success(parsed_value);
  }

  static std::string RemovePrefix(const std::string& source) {
    size_t prefix_idx = source.find(":");

    if (prefix_idx == std::string::npos) {
      return "";
    }

    return source.substr(prefix_idx + 1);
  }

 public:
  Result ParseAndAppend(const std::string& option, TestProfilerOptions& existing) {
    // Special case which doesn't include a wildcard argument definition.
    // We pass-it through as-is.
    if (option == "-Xenable-profiler") {
      existing.enabled_ = true;
      return Result::SuccessNoValue();
    }

    // The rest of these options are always the wildcard from '-Xprofile-*'
    std::string suffix = RemovePrefix(option);

    if (StartsWith(option, "filename:")) {
      CmdlineType<std::string> type_parser;

      return ParseInto(existing,
                       &TestProfilerOptions::output_file_name_,
                       type_parser.Parse(suffix));
    } else if (StartsWith(option, "period:")) {
      CmdlineType<unsigned int> type_parser;

      return ParseInto(existing,
                       &TestProfilerOptions::period_s_,
                       type_parser.Parse(suffix));
    } else if (StartsWith(option, "duration:")) {
      CmdlineType<unsigned int> type_parser;

      return ParseInto(existing,
                       &TestProfilerOptions::duration_s_,
                       type_parser.Parse(suffix));
    } else if (StartsWith(option, "interval:")) {
      CmdlineType<unsigned int> type_parser;

      return ParseInto(existing,
                       &TestProfilerOptions::interval_us_,
                       type_parser.Parse(suffix));
    } else if (StartsWith(option, "backoff:")) {
      CmdlineType<double> type_parser;

      return ParseIntoRangeCheck(existing,
                                 &TestProfilerOptions::backoff_coefficient_,
                                 type_parser.Parse(suffix),
                                 1.0,
                                 10.0);

    } else if (option == "start-immediately") {
      existing.start_immediately_ = true;
      return Result::SuccessNoValue();
    } else if (StartsWith(option, "top-k-threshold:")) {
      CmdlineType<double> type_parser;

      return ParseIntoRangeCheck(existing,
                                 &TestProfilerOptions::top_k_threshold_,
                                 type_parser.Parse(suffix),
                                 0.0,
                                 100.0);
    } else if (StartsWith(option, "top-k-change-threshold:")) {
      CmdlineType<double> type_parser;

      return ParseIntoRangeCheck(existing,
                                 &TestProfilerOptions::top_k_change_threshold_,
                                 type_parser.Parse(suffix),
                                 0.0,
                                 100.0);
    } else if (option == "type:method") {
      existing.profile_type_ = kProfilerMethod;
      return Result::SuccessNoValue();
    } else if (option == "type:stack") {
      existing.profile_type_ = kProfilerBoundedStack;
      return Result::SuccessNoValue();
    } else if (StartsWith(option, "max-stack-depth:")) {
      CmdlineType<unsigned int> type_parser;

      return ParseInto(existing,
                       &TestProfilerOptions::max_stack_depth_,
                       type_parser.Parse(suffix));
    } else {
      return Result::Failure(std::string("Invalid suboption '") + option + "'");
    }
  }

  static const char* Name() { return "TestProfilerOptions"; }
  static constexpr bool kCanParseBlankless = true;
};


}  // namespace art
#endif  // ART_CMDLINE_CMDLINE_TYPES_H_
