/*
 * 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&) = default;
  MillisecondsToNanoseconds(MillisecondsToNanoseconds&&) = 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&) = default;
  ParseStringList(ParseStringList&&) = 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] == "jit") {
        log_verbosity.jit = 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] == "oat") {
        log_verbosity.oat = 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&) = default;
  TestProfilerOptions(TestProfilerOptions&&) = 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_
