// Copyright 2019 Google LLC
//
// 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
//
//     https://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.

// View class template for enums.
#ifndef EMBOSS_RUNTIME_CPP_EMBOSS_ENUM_VIEW_H_
#define EMBOSS_RUNTIME_CPP_EMBOSS_ENUM_VIEW_H_

#include <cctype>
#include <cstdint>
#include <string>
#include <utility>

#include "runtime/cpp/emboss_text_util.h"
#include "runtime/cpp/emboss_view_parameters.h"

namespace emboss {
namespace support {

// EnumView is a view for Enums inside of bitfields.
template <class Enum, class Parameters, class BitViewType>
class EnumView final {
 public:
  using ValueType = typename ::std::remove_cv<Enum>::type;
  static_assert(
      Parameters::kBits <= sizeof(ValueType) * 8,
      "EnumView requires sizeof(ValueType) * 8 >= Parameters::kBits.");
  template <typename... Args>
  explicit EnumView(Args &&... args) : buffer_{::std::forward<Args>(args)...} {}
  EnumView() : buffer_() {}
  EnumView(const EnumView &) = default;
  EnumView(EnumView &&) = default;
  EnumView &operator=(const EnumView &) = default;
  EnumView &operator=(EnumView &&) = default;
  ~EnumView() = default;

  // TODO(bolms): Here and in CouldWriteValue(), the static_casts to ValueType
  // rely on implementation-defined behavior when ValueType is signed.
  ValueType Read() const {
    ValueType result = static_cast<ValueType>(buffer_.ReadUInt());
    EMBOSS_CHECK(Parameters::ValueIsOk(result));
    return result;
  }
  ValueType UncheckedRead() const {
    return static_cast<ValueType>(buffer_.UncheckedReadUInt());
  }
  void Write(ValueType value) const {
    const bool result = TryToWrite(value);
    (void)result;
    EMBOSS_CHECK(result);
  }
  bool TryToWrite(ValueType value) const {
    if (!CouldWriteValue(value)) return false;
    if (!IsComplete()) return false;
    buffer_.WriteUInt(static_cast<typename BitViewType::ValueType>(value));
    return true;
  }
  static constexpr bool CouldWriteValue(ValueType value) {
    // The value can be written if:
    //
    // a) it can fit in BitViewType::ValueType (verified by casting to
    //    BitViewType::ValueType and back, and making sure that the value is
    //    unchanged)
    //
    // and either:
    //
    // b1) the field size is large enough to hold all values, or
    // b2) the value is less than 2**(field size in bits)
    return value == static_cast<ValueType>(
                        static_cast<typename BitViewType::ValueType>(value)) &&
           ((Parameters::kBits ==
             sizeof(typename BitViewType::ValueType) * 8) ||
            (static_cast<typename BitViewType::ValueType>(value) <
             ((static_cast<typename BitViewType::ValueType>(1)
               << (Parameters::kBits - 1))
              << 1))) &&
           Parameters::ValueIsOk(value);
  }
  void UncheckedWrite(ValueType value) const {
    buffer_.UncheckedWriteUInt(
        static_cast<typename BitViewType::ValueType>(value));
  }

  template <typename OtherView>
  void CopyFrom(const OtherView &other) const {
    Write(other.Read());
  }
  template <typename OtherView>
  void UncheckedCopyFrom(const OtherView &other) const {
    UncheckedWrite(other.UncheckedRead());
  }
  template <typename OtherView>
  bool TryToCopyFrom(const OtherView &other) const {
    return other.Ok() && TryToWrite(other.Read());
  }

  // All bit patterns in the underlying buffer are valid, so Ok() is always
  // true if IsComplete() is true.
  bool Ok() const {
    return IsComplete() && Parameters::ValueIsOk(UncheckedRead());
  }
  template <class OtherBitViewType>
  bool Equals(const EnumView<Enum, Parameters, OtherBitViewType> &other) const {
    return Read() == other.Read();
  }
  template <class OtherBitViewType>
  bool UncheckedEquals(
      const EnumView<Enum, Parameters, OtherBitViewType> &other) const {
    return UncheckedRead() == other.UncheckedRead();
  }
  bool IsComplete() const {
    return buffer_.Ok() && buffer_.SizeInBits() >= Parameters::kBits;
  }

  template <class Stream>
  bool UpdateFromTextStream(Stream *stream) const {
    ::std::string token;
    if (!ReadToken(stream, &token)) return false;
    if (token.empty()) return false;
    if (::std::isdigit(token[0])) {
      ::std::uint64_t value;
      if (!DecodeInteger(token, &value)) return false;
      // TODO(bolms): Fix the static_cast<ValueType> for signed ValueType.
      // TODO(bolms): Should values between 2**63 and 2**64-1 actually be
      // allowed in the text format when ValueType is signed?
      return TryToWrite(static_cast<ValueType>(value));
    } else if (token[0] == '-') {
      ::std::int64_t value;
      if (!DecodeInteger(token, &value)) return false;
      return TryToWrite(static_cast<ValueType>(value));
    } else {
      ValueType value;
      if (!TryToGetEnumFromName(token.c_str(), &value)) return false;
      return TryToWrite(value);
    }
  }

  template <class Stream>
  void WriteToTextStream(Stream *stream,
                         const TextOutputOptions &options) const {
    ::emboss::support::WriteEnumViewToTextStream(this, stream, options);
  }

  static constexpr bool IsAggregate() { return false; }

  static constexpr int SizeInBits() { return Parameters::kBits; }

 private:
  BitViewType buffer_;
};

}  // namespace support
}  // namespace emboss

#endif  // EMBOSS_RUNTIME_CPP_EMBOSS_ENUM_VIEW_H_
