// 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_PUBLIC_EMBOSS_ENUM_VIEW_H_
#define EMBOSS_PUBLIC_EMBOSS_ENUM_VIEW_H_

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

#include "public/emboss_text_util.h"
#include "public/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 { EMBOSS_CHECK(TryToWrite(value)); }
  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 int SizeInBits() { return Parameters::kBits; }

 private:
  BitViewType buffer_;
};

}  // namespace support
}  // namespace emboss

#endif  // EMBOSS_PUBLIC_EMBOSS_ENUM_VIEW_H_
