/*
 * Copyright (C) 2023 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 <memory>
#include <optional>
#include <string>
#include <unordered_map>
#include <variant>
#include <vector>

#include "common/libs/utils/contains.h"
#include "common/libs/utils/flag_parser.h"
#include "common/libs/utils/result.h"
#include "host/commands/cvd/types.h"

namespace cuttlefish {

/**
 * Data structure to represent cvd user-facing flags
 *
 * Flag in flag_parser.h is more on parsing. gflags library would be
 * slowly depreicated. The cvd driver and selector flags are a specification for
 * a user-facing flag.
 */
template <typename T>
class CvdFlag {
 public:
  using GflagFactoryCallback =
      std::function<Flag(const std::string& name, T& value_out)>;
  CvdFlag(const std::string& name)
      : name_(name),
        gflag_factory_cb([](const std::string& name, T& value_out) {
          return GflagsCompatFlag(name, value_out);
        }) {}

  CvdFlag(const std::string& name, const T& default_value)
      : name_(name),
        default_value_(default_value),
        gflag_factory_cb([](const std::string& name, T& value_out) {
          return GflagsCompatFlag(name, value_out);
        }) {}

  std::string Name() const { return name_; }
  std::string HelpMessage() const { return help_msg_; }
  CvdFlag& SetHelpMessage(const std::string& help_msg) & {
    help_msg_ = help_msg;
    return *this;
  }
  CvdFlag SetHelpMessage(const std::string& help_msg) && {
    help_msg_ = help_msg;
    return *this;
  }
  bool HasDefaultValue() const { return default_value_ != std::nullopt; }
  Result<T> DefaultValue() const {
    CF_EXPECT(HasDefaultValue());
    return *default_value_;
  }

  CvdFlag& SetGflagFactory(GflagFactoryCallback factory) & {
    gflag_factory_cb = std::move(factory);
    return *this;
  }
  CvdFlag SetGflagFactory(GflagFactoryCallback factory) && {
    gflag_factory_cb = std::move(factory);
    return *this;
  }

  // returns CF_ERR if parsing error,
  // returns std::nullopt if parsing was okay but the flag wasn't given
  Result<std::optional<T>> FilterFlag(cvd_common::Args& args) const {
    const int args_initial_size = args.size();
    if (args_initial_size == 0) {
      return std::nullopt;
    }
    T value;
    CF_EXPECT(ParseFlags({gflag_factory_cb(name_, value)}, args),
              "Failed to parse --" << name_);
    if (args.size() == args_initial_size) {
      // not consumed
      return std::nullopt;
    }
    return value;
  }

  // Parses the arguments. If flag is given, returns the parsed value. If not,
  // returns the default value if any. If no default value, it returns CF_ERR.
  Result<T> CalculateFlag(cvd_common::Args& args) const {
    auto value_opt = CF_EXPECT(FilterFlag(args));
    if (!value_opt) {
      CF_EXPECT(default_value_ != std::nullopt);
      value_opt = default_value_;
    }
    return *value_opt;
  }

 private:
  const std::string name_;
  std::string help_msg_;
  std::optional<T> default_value_;
  /**
   * A callback function to generate Flag defined in
   * common/libs/utils/flag_parser.h. The name is this CvdFlag's name.
   * The value is a buffer that is kept in this object
   */
  GflagFactoryCallback gflag_factory_cb;
};

class CvdFlagProxy {
  friend class FlagCollection;

 public:
  enum class FlagType : std::uint32_t {
    kUnknown = 0,
    kBool,
    kInt32,
    kString,
  };

  static std::string ToString(const FlagType flag_type) {
    switch (flag_type) {
      case FlagType::kUnknown:
        return "kUnknown";
      case FlagType::kBool:
        return "bool";
      case FlagType::kInt32:
        return "std::int32_t";
      case FlagType::kString:
        return "std::string";
    }
  }

  template <typename T>
  CvdFlagProxy(CvdFlag<T>&& flag) : flag_{std::move(flag)} {}

  template <typename T>
  const CvdFlag<T>* GetFlag() const {
    return std::get_if<CvdFlag<T>>(&flag_);
  }

  template <typename T>
  CvdFlag<T>* GetFlag() {
    return std::get_if<CvdFlag<T>>(&flag_);
  }

  /*
   * If the actual type of flag_ is not handled by SelectorFlagProxy, it is a
   * developer error, and the Name() and HasDefaultValue() will returns
   * CF_ERR
   */
  Result<std::string> Name() const;
  Result<bool> HasDefaultValue() const;

  FlagType GetType() const;

  template <typename T>
  Result<T> DefaultValue() const {
    const bool has_default_value = CF_EXPECT(HasDefaultValue());
    CF_EXPECT(has_default_value == true);
    const auto* ptr = CF_EXPECT(std::get_if<CvdFlag<T>>(&flag_));
    CF_EXPECT(ptr != nullptr);
    return ptr->DefaultValue();
  }

  // returns CF_ERR if parsing error,
  // returns std::nullopt if parsing was okay but the flag wasn't given
  template <typename T>
  Result<std::optional<T>> FilterFlag(cvd_common::Args& args) const {
    std::optional<T> output;
    const auto* ptr = CF_EXPECT(std::get_if<CvdFlag<T>>(&flag_));
    CF_EXPECT(ptr != nullptr);
    output = CF_EXPECT(ptr->FilterFlag(args));
    return output;
  }

  // Parses the arguments. If flag is given, returns the parsed value. If not,
  // returns the default value if any. If no default value, it returns CF_ERR.
  template <typename T>
  Result<T> CalculateFlag(cvd_common::Args& args) const {
    bool has_default_value = CF_EXPECT(HasDefaultValue());
    CF_EXPECT(has_default_value == true);
    const auto* ptr = CF_EXPECT(std::get_if<CvdFlag<T>>(&flag_));
    CF_EXPECT(ptr != nullptr);
    T output = CF_EXPECT(ptr->CalculateFlag(args));
    return output;
  }

  using ValueVariant = std::variant<std::int32_t, bool, std::string>;

  // Returns std::nullopt when the parsing goes okay but the flag wasn't given
  // Returns ValueVariant when the flag was given in args
  // Returns CF_ERR when the parsing failed or the type is not supported
  Result<std::optional<ValueVariant>> FilterFlag(cvd_common::Args& args) const;

 private:
  std::variant<CvdFlag<std::int32_t>, CvdFlag<bool>, CvdFlag<std::string>>
      flag_;
};

class FlagCollection {
 public:
  using ValueVariant = CvdFlagProxy::ValueVariant;

  Result<void> EnrollFlag(CvdFlagProxy&& flag) {
    auto name = CF_EXPECT(flag.Name());
    CF_EXPECT(!Contains(name_flag_map_, name),
              name << " is already registered.");
    name_flag_map_.emplace(name, std::move(flag));
    return {};
  }

  template <typename T>
  Result<void> EnrollFlag(CvdFlag<T>&& flag) {
    CF_EXPECT(EnrollFlag(CvdFlagProxy(std::move(flag))));
    return {};
  }

  Result<CvdFlagProxy> GetFlag(const std::string& name) const {
    const auto itr = name_flag_map_.find(name);
    CF_EXPECT(itr != name_flag_map_.end(),
              "Flag \"" << name << "\" is not found.");
    const CvdFlagProxy& flag_proxy = itr->second;
    return flag_proxy;
  }

  std::vector<CvdFlagProxy> Flags() const;

  struct FlagValuePair {
    CvdFlagProxy flag;
    ValueVariant value;
  };

  /* does not consider default values
   * so, if not default value and the flag wasn't given, it won't be found
   * in the returned map
   */
  Result<std::unordered_map<std::string, FlagValuePair>> FilterFlags(
      cvd_common::Args& args) const;

  /* considers default values
   * so, if the flag wasn't given, the default value will be used to fill
   * out the returned map. If a default value isn't available and the flag
   * isn't given either, the entry won't be in the returned map
   */
  Result<std::unordered_map<std::string, FlagValuePair>> CalculateFlags(
      cvd_common::Args& args) const;

  template <typename T>
  static Result<T> GetValue(const ValueVariant& value_variant) {
    auto* value_ptr = std::get_if<T>(std::addressof(value_variant));
    CF_EXPECT(value_ptr != nullptr,
              "GetValue template function was instantiated with a wrong type.");
    return *value_ptr;
  }

  template <typename T>
  static Result<T> GetValue(const FlagValuePair& flag_and_value) {
    std::string flag_type_string =
        CvdFlagProxy::ToString(flag_and_value.flag.GetType());
    auto* value_ptr = std::get_if<T>(std::addressof(flag_and_value.value));
    CF_EXPECT(value_ptr != nullptr,
              "The actual flag type is " << flag_type_string);
    return *value_ptr;
  }

 private:
  std::unordered_map<std::string, CvdFlagProxy> name_flag_map_;
};

}  // namespace cuttlefish
