/*
 * Copyright (C) 2021 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.
 */

#pragma once

#include <cstdint>
#include <functional>
#include <optional>
#include <ostream>
#include <string>
#include <vector>

/* Support for parsing individual flags out of a larger list of flags. This
 * supports externally determining the order that flags are evaluated in, and
 * incrementally integrating with existing flag parsing implementations.
 *
 * Start with Flag() or one of the GflagsCompatFlag(...) functions to create new
 * flags. These flags should be aggregated through the application through some
 * other mechanism and then evaluated individually with Flag::Parse or together
 * with ParseFlags on arguments. */

namespace cuttlefish {

/* The matching behavior used with the name in `FlagAlias::name`. */
enum class FlagAliasMode {
  /* Match arguments of the form `<name><value>`. In practice, <name> usually
   * looks like "-flag=" or "--flag=", where the "-" and "=" are included in
   * parsing. */
  kFlagPrefix,
  /* Match arguments of the form `<name>`. In practice, <name> will look like
   * "-flag" or "--flag". */
  kFlagExact,
  /* Match a pair of arguments of the form `<name>` `<value>`. In practice,
   * <name> will look like "-flag" or "--flag". */
  kFlagConsumesFollowing,
  /* Match a sequence of arguments of the form `<name>` `<value>` `<value>`.
   * This uses heuristics to try to determine when `<value>` is actually another
   * flag. */
  kFlagConsumesArbitrary,
};

/* A single matching rule for a `Flag`. One `Flag` can have multiple rules. */
struct FlagAlias {
  FlagAliasMode mode;
  std::string name;
};

std::ostream& operator<<(std::ostream&, const FlagAlias&);

/* A successful match in an argument list from a `FlagAlias` inside a `Flag`.
 * The `key` value corresponds to `FlagAlias::name`. For a match of
 * `FlagAliasMode::kFlagExact`, `key` and `value` will both be the `name`. */
struct FlagMatch {
  std::string key;
  std::string value;
};

class Flag {
 public:
  /* Add an alias that triggers matches and calls to the `Setter` function. */
  Flag& Alias(const FlagAlias& alias) &;
  Flag Alias(const FlagAlias& alias) &&;
  /* Set help text, visible in the class ostream writer method. Optional. */
  Flag& Help(const std::string&) &;
  Flag Help(const std::string&) &&;
  /* Set a loader that displays the current value in help text. Optional. */
  Flag& Getter(std::function<std::string()>) &;
  Flag Getter(std::function<std::string()>) &&;
  /* Set the callback for matches. The callback be invoked multiple times. */
  Flag& Setter(std::function<bool(const FlagMatch&)>) &;
  Flag Setter(std::function<bool(const FlagMatch&)>) &&;

  /* Examines a list of arguments, removing any matches from the list and
   * invoking the `Setter` for every match. Returns `false` if the callback ever
   * returns `false`. Non-matches are left in place. */
  bool Parse(std::vector<std::string>& flags) const;
  bool Parse(std::vector<std::string>&& flags) const;

  /* Write gflags `--helpxml` style output for a string-type flag. */
  bool WriteGflagsCompatXml(std::ostream&) const;

 private:
  /* Reports whether `Process` wants to consume zero, one, or two arguments. */
  enum class FlagProcessResult {
    /* Error in handling a flag, exit flag handling with an error result. */
    kFlagError,
    kFlagSkip,                  /* Flag skipped; consume no arguments. */
    kFlagConsumed,              /* Flag processed; consume one argument. */
    kFlagConsumedWithFollowing, /* Flag processed; consume 2 arguments. */
    kFlagConsumedOnlyFollowing, /* Flag processed; consume next argument. */
  };

  void ValidateAlias(const FlagAlias& alias);
  Flag& UnvalidatedAlias(const FlagAlias& alias) &;
  Flag UnvalidatedAlias(const FlagAlias& alias) &&;

  /* Attempt to match a single argument. */
  FlagProcessResult Process(const std::string& argument,
                            const std::optional<std::string>& next_arg) const;

  bool HasAlias(const FlagAlias&) const;

  friend std::ostream& operator<<(std::ostream&, const Flag&);
  friend Flag InvalidFlagGuard();
  friend Flag UnexpectedArgumentGuard();

  std::vector<FlagAlias> aliases_;
  std::optional<std::string> help_;
  std::optional<std::function<std::string()>> getter_;
  std::optional<std::function<bool(const FlagMatch&)>> setter_;
};

std::ostream& operator<<(std::ostream&, const Flag&);

std::vector<std::string> ArgsToVec(int argc, char** argv);

/* Handles a list of flags. Flags are matched in the order given in case two
 * flags match the same argument. Matched flags are removed, leaving only
 * unmatched arguments. */
bool ParseFlags(const std::vector<Flag>& flags, std::vector<std::string>& args);
bool ParseFlags(const std::vector<Flag>& flags, std::vector<std::string>&&);

bool WriteGflagsCompatXml(const std::vector<Flag>&, std::ostream&);

/* If any of these are used, they should be evaluated after all other flags, and
 * in the order defined here (help before invalid flags, invalid flags before
 * unexpected arguments). */

/* If a "-help" or "--help" flag is present, prints all the flags and fails. */
Flag HelpFlag(const std::vector<Flag>& flags, const std::string& text = "");
/* Catches unrecognized arguments that begin with `-`, and errors out. This
 * effectively denies unknown flags. */
Flag InvalidFlagGuard();
/* Catches any arguments not extracted by other Flag matchers and errors out.
 * This effectively denies unknown flags and any positional arguments. */
Flag UnexpectedArgumentGuard();

// Create a flag resembling a gflags argument of the given type. This includes
// "-[-]flag=*",support for all types, "-[-]noflag" support for booleans, and
// "-flag *", "--flag *", support for other types. The value passed in the flag
// is saved to the defined reference.
Flag GflagsCompatFlag(const std::string& name);
Flag GflagsCompatFlag(const std::string& name, std::string& value);
Flag GflagsCompatFlag(const std::string& name, std::int32_t& value);
Flag GflagsCompatFlag(const std::string& name, bool& value);

}  // namespace cuttlefish
