// Copyright 2017-2020 The Verible Authors.
//
// 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 VERIBLE_COMMON_UTIL_ENUM_FLAGS_H_
#define VERIBLE_COMMON_UTIL_ENUM_FLAGS_H_

#include <initializer_list>
#include <sstream>
#include <string>
#include <utility>

#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
#include "common/strings/compare.h"
#include "common/util/bijective_map.h"

namespace verible {

namespace internal {
// Functor that extracts the first element of a pair and appends it to a string.
// Suitable for use with absl::StrJoin()'s formatter arguments.
struct FirstElementFormatter {
  template <class P>
  void operator()(std::string* out, const P& p) const {
    out->append(p.first.begin(), p.first.end());
  }
};

// For enums to be comparable for uniqueness/mapping sake,
// force interpret them as integers.
struct EnumCompare {
  template <class E>
  bool operator()(E left, E right) const {
    return static_cast<int>(left) < static_cast<int>(right);
  }
};
}  // namespace internal

/**
EnumNameMap provides a consistent way to parse and unparse enumerations with
string/named representations.
This makes enumeration types easy to use with absl flags.

Usage:

////////////////// .h header file ///////////////////
// Define an enum in public header.
enum class MyEnumType { ... };

// Conventional stream printer (declared in header providing enum).
std::ostream& operator<<(std::ostream& stream, MyEnumType p);

// If making this usable as an absl flag, provide the following overloads:
bool AbslParseFlag(absl::string_view text, MyEnumType* mode,
                   std::string* error);
std::string AbslUnparseFlag(const MyEnumType& mode);


/////////////// .cc implementation file ////////////////
const EnumNameMap<MyEnumType> MyEnumTypeNames{{
  {"enum1", MyEnumType::kEnum1},
  {"enum2", MyEnumType::kEnum2},
  ...
}};

std::ostream& operator<<(std::ostream& stream, MyEnumType p) {
  return MyEnumTypeNames.Unparse(p, stream);
}

bool AbslParseFlag(absl::string_view text, MyEnumType* mode,
                   std::string* error) {
  return kLanguageModeStringMap.Parse(text, mode, error, "MyEnumType");
}

std::string AbslUnparseFlag(const MyEnumType& mode) {
  std::ostringstream stream;
  stream << mode;
  return stream.str();
}

**/
template <typename EnumType>
class EnumNameMap {
  // Using a string_view is safe when the string-memory owned elsewhere is
  // guaranteed to outlive objects of this class.
  // String-literals are acceptable sources of string_views for this purpose.
  typedef absl::string_view key_type;

  // Storage type for mapping information.
  // StringViewCompare gives the benefit of copy-free heterogeneous lookup.
  typedef BijectiveMap<key_type, EnumType, StringViewCompare,
                       internal::EnumCompare>
      map_type;

 public:
  // Pairs must contain unique keys or values, or this will result in a fatal
  // error.
  EnumNameMap(std::initializer_list<std::pair<key_type, EnumType>> pairs)
      : enum_name_map_(pairs) {}
  ~EnumNameMap() = default;

  EnumNameMap(const EnumNameMap&) = delete;
  EnumNameMap(EnumNameMap&&) = delete;
  EnumNameMap& operator=(const EnumNameMap&) = delete;
  EnumNameMap& operator=(EnumNameMap&&) = delete;

  // Print a list of string representations of the enums.
  std::ostream& ListNames(std::ostream& stream, absl::string_view sep) const {
    return stream << absl::StrJoin(enum_name_map_.forward_view(), sep,
                                   internal::FirstElementFormatter());
  }

  // Converts the name of an enum to its corresponding value.
  // 'type_name' is a text name for the enum type used in diagnostics.
  // This variant write diagnostics to the 'errstream' stream.
  // Returns true if successful.
  bool Parse(key_type text, EnumType* enum_value, std::ostream& errstream,
             absl::string_view type_name) const {
    const EnumType* found_value = enum_name_map_.find_forward(text);
    if (found_value != nullptr) {
      *enum_value = *found_value;
      return true;
    } else {
      errstream << "Invalid " << type_name << ": '" << text
                << "'\nValid options are: ";
      ListNames(errstream, ",");
      return false;
    }
  }

  // Converts the name of an enum to its corresponding value.
  // This variant write diagnostics to the 'error' string.
  bool Parse(key_type text, EnumType* enum_value, std::string* error,
             absl::string_view type_name) const {
    std::ostringstream stream;
    const bool success = Parse(text, enum_value, stream, type_name);
    *error += stream.str();
    return success;
  }

  // Returns the string representation of an enum.
  absl::string_view EnumName(EnumType value) const {
    const auto* key = enum_name_map_.find_reverse(value);
    if (key == nullptr) return "???";
    return *key;
  }

  // Prints the string representation of an enum to stream.
  std::ostream& Unparse(EnumType value, std::ostream& stream) const {
    return stream << EnumName(value);
  }

 protected:  // for testing
  // Stores the enum/string mapping.
  map_type enum_name_map_;
};

}  // namespace verible

#endif  // VERIBLE_COMMON_UTIL_ENUM_FLAGS_H_
