// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef TOOLS_FIDL_FIDLC_INCLUDE_FIDL_FLAT_VALUES_H_
#define TOOLS_FIDL_FIDLC_INCLUDE_FIDL_FLAT_VALUES_H_

namespace fidl {
namespace flat {

// ConstantValue represents the concrete _value_ of a constant. (For the
// _declaration_, see Const. For the _use_, see Constant.) ConstantValue has
// derived classes for all the different kinds of constants.
struct ConstantValue {
  virtual ~ConstantValue() {}

  enum struct Kind {
    kInt8,
    kInt16,
    kInt32,
    kInt64,
    kUint8,
    kUint16,
    kUint32,
    kUint64,
    kFloat32,
    kFloat64,
    kBool,
    kString,
  };

  virtual bool Convert(Kind kind, std::unique_ptr<ConstantValue>* out_value) const = 0;

  const Kind kind;

 protected:
  explicit ConstantValue(Kind kind) : kind(kind) {}
};

template <typename ValueType>
struct NumericConstantValue final : ConstantValue {
  static_assert(std::is_arithmetic<ValueType>::value && !std::is_same<ValueType, bool>::value,
                "NumericConstantValue can only be used with a numeric ValueType!");

  NumericConstantValue(ValueType value) : ConstantValue(GetKind()), value(value) {}

  operator ValueType() const { return value; }

  friend bool operator==(const NumericConstantValue<ValueType>& l,
                         const NumericConstantValue<ValueType>& r) {
    return l.value == r.value;
  }

  friend bool operator<(const NumericConstantValue<ValueType>& l,
                        const NumericConstantValue<ValueType>& r) {
    return l.value < r.value;
  }

  friend bool operator>(const NumericConstantValue<ValueType>& l,
                        const NumericConstantValue<ValueType>& r) {
    return l.value > r.value;
  }

  friend bool operator!=(const NumericConstantValue<ValueType>& l,
                         const NumericConstantValue<ValueType>& r) {
    return l.value != r.value;
  }

  friend bool operator<=(const NumericConstantValue<ValueType>& l,
                         const NumericConstantValue<ValueType>& r) {
    return l.value <= r.value;
  }

  friend bool operator>=(const NumericConstantValue<ValueType>& l,
                         const NumericConstantValue<ValueType>& r) {
    return l.value >= r.value;
  }

  friend NumericConstantValue<ValueType> operator|(const NumericConstantValue<ValueType>& l,
                                                   const NumericConstantValue<ValueType>& r) {
    static_assert(!std::is_same_v<ValueType, float> && !std::is_same_v<ValueType, double>);
    return NumericConstantValue<ValueType>(l.value | r.value);
  }

  friend std::ostream& operator<<(std::ostream& os, const NumericConstantValue<ValueType>& v) {
    if constexpr (GetKind() == Kind::kInt8)
      os << static_cast<int>(v.value);
    else if constexpr (GetKind() == Kind::kUint8)
      os << static_cast<unsigned>(v.value);
    else
      os << v.value;
    return os;
  }

  virtual bool Convert(Kind kind, std::unique_ptr<ConstantValue>* out_value) const override {
    assert(out_value != nullptr);

    auto checked_value = safemath::CheckedNumeric<ValueType>(value);

    switch (kind) {
      case Kind::kInt8: {
        int8_t casted_value;
        if (!checked_value.template Cast<int8_t>().AssignIfValid(&casted_value)) {
          return false;
        }
        *out_value = std::make_unique<NumericConstantValue<int8_t>>(casted_value);
        return true;
      }
      case Kind::kInt16: {
        int16_t casted_value;
        if (!checked_value.template Cast<int16_t>().AssignIfValid(&casted_value)) {
          return false;
        }
        *out_value = std::make_unique<NumericConstantValue<int16_t>>(casted_value);
        return true;
      }
      case Kind::kInt32: {
        int32_t casted_value;
        if (!checked_value.template Cast<int32_t>().AssignIfValid(&casted_value)) {
          return false;
        }
        *out_value = std::make_unique<NumericConstantValue<int32_t>>(casted_value);
        return true;
      }
      case Kind::kInt64: {
        int64_t casted_value;
        if (!checked_value.template Cast<int64_t>().AssignIfValid(&casted_value)) {
          return false;
        }
        *out_value = std::make_unique<NumericConstantValue<int64_t>>(casted_value);
        return true;
      }
      case Kind::kUint8: {
        uint8_t casted_value;
        if (!checked_value.template Cast<uint8_t>().AssignIfValid(&casted_value)) {
          return false;
        }
        *out_value = std::make_unique<NumericConstantValue<uint8_t>>(casted_value);
        return true;
      }
      case Kind::kUint16: {
        uint16_t casted_value;
        if (!checked_value.template Cast<uint16_t>().AssignIfValid(&casted_value)) {
          return false;
        }
        *out_value = std::make_unique<NumericConstantValue<uint16_t>>(casted_value);
        return true;
      }
      case Kind::kUint32: {
        uint32_t casted_value;
        if (!checked_value.template Cast<uint32_t>().AssignIfValid(&casted_value)) {
          return false;
        }
        *out_value = std::make_unique<NumericConstantValue<uint32_t>>(casted_value);
        return true;
      }
      case Kind::kUint64: {
        uint64_t casted_value;
        if (!checked_value.template Cast<uint64_t>().AssignIfValid(&casted_value)) {
          return false;
        }
        *out_value = std::make_unique<NumericConstantValue<uint64_t>>(casted_value);
        return true;
      }
      case Kind::kFloat32: {
        float casted_value;
        if (!checked_value.template Cast<float>().AssignIfValid(&casted_value)) {
          return false;
        }
        *out_value = std::make_unique<NumericConstantValue<float>>(casted_value);
        return true;
      }
      case Kind::kFloat64: {
        double casted_value;
        if (!checked_value.template Cast<double>().AssignIfValid(&casted_value)) {
          return false;
        }
        *out_value = std::make_unique<NumericConstantValue<double>>(casted_value);
        return true;
      }
      case Kind::kString:
      case Kind::kBool:
        return false;
    }
  }

  static NumericConstantValue<ValueType> Min() {
    return NumericConstantValue<ValueType>(std::numeric_limits<ValueType>::lowest());
  }

  static NumericConstantValue<ValueType> Max() {
    return NumericConstantValue<ValueType>(std::numeric_limits<ValueType>::max());
  }

  ValueType value;

 private:
  constexpr static Kind GetKind() {
    if constexpr (std::is_same_v<ValueType, uint64_t>)
      return Kind::kUint64;
    if constexpr (std::is_same_v<ValueType, int64_t>)
      return Kind::kInt64;
    if constexpr (std::is_same_v<ValueType, uint32_t>)
      return Kind::kUint32;
    if constexpr (std::is_same_v<ValueType, int32_t>)
      return Kind::kInt32;
    if constexpr (std::is_same_v<ValueType, uint16_t>)
      return Kind::kUint16;
    if constexpr (std::is_same_v<ValueType, int16_t>)
      return Kind::kInt16;
    if constexpr (std::is_same_v<ValueType, uint8_t>)
      return Kind::kUint8;
    if constexpr (std::is_same_v<ValueType, int8_t>)
      return Kind::kInt8;
    if constexpr (std::is_same_v<ValueType, double>)
      return Kind::kFloat64;
    if constexpr (std::is_same_v<ValueType, float>)
      return Kind::kFloat32;
  }
};

using Size = NumericConstantValue<uint32_t>;

struct BoolConstantValue final : ConstantValue {
  BoolConstantValue(bool value) : ConstantValue(ConstantValue::Kind::kBool), value(value) {}

  operator bool() const { return value; }

  friend bool operator==(const BoolConstantValue& l, const BoolConstantValue& r) {
    return l.value == r.value;
  }

  friend bool operator!=(const BoolConstantValue& l, const BoolConstantValue& r) {
    return l.value != r.value;
  }

  friend std::ostream& operator<<(std::ostream& os, const BoolConstantValue& v) {
    os << v.value;
    return os;
  }

  virtual bool Convert(Kind kind, std::unique_ptr<ConstantValue>* out_value) const override {
    assert(out_value != nullptr);
    switch (kind) {
      case Kind::kBool:
        *out_value = std::make_unique<BoolConstantValue>(value);
        return true;
      default:
        return false;
    }
  }

  bool value;
};

struct StringConstantValue final : ConstantValue {
  explicit StringConstantValue(std::string_view value)
      : ConstantValue(ConstantValue::Kind::kString), value(value) {}

  friend std::ostream& operator<<(std::ostream& os, const StringConstantValue& v) {
    os << v.value.data();
    return os;
  }

  virtual bool Convert(Kind kind, std::unique_ptr<ConstantValue>* out_value) const override {
    assert(out_value != nullptr);
    switch (kind) {
      case Kind::kString:
        *out_value = std::make_unique<StringConstantValue>(std::string_view(value));
        return true;
      default:
        return false;
    }
  }

  std::string_view value;
};

// Constant represents the _use_ of a constant. (For the _declaration_, see
// Const. For the _value_, see ConstantValue.) A Constant can either be a
// reference to another constant (IdentifierConstant), a literal value
// (LiteralConstant), or synthesized by the compiler (SynthesizedConstant).
// Every Constant resolves to a concrete ConstantValue.
struct Constant {
  virtual ~Constant() {}

  enum struct Kind { kIdentifier, kLiteral, kSynthesized, kBinaryOperator };

  explicit Constant(Kind kind, SourceSpan span) : kind(kind), span(span), value_(nullptr) {}

  bool IsResolved() const { return value_ != nullptr; }

  void ResolveTo(std::unique_ptr<ConstantValue> value) {
    assert(value != nullptr);
    assert(!IsResolved() && "Constants should only be resolved once!");
    value_ = std::move(value);
  }

  const ConstantValue& Value() const {
    if (!IsResolved()) {
      std::cout << span.data() << std::endl;
    }
    assert(IsResolved() && "Accessing the value of an unresolved Constant!");
    return *value_;
  }

  const Kind kind;
  const SourceSpan span;
  // compiled tracks whether we attempted to resolve this constant, to avoid
  // resolving twice a constant which cannot be resolved.
  bool compiled = false;

 protected:
  std::unique_ptr<ConstantValue> value_;
};

struct IdentifierConstant final : Constant {
  explicit IdentifierConstant(Name name, SourceSpan span)
      : Constant(Kind::kIdentifier, span), name(std::move(name)) {}

  const Name name;
};

struct LiteralConstant final : Constant {
  explicit LiteralConstant(std::unique_ptr<raw::Literal> literal)
      : Constant(Kind::kLiteral, literal->span()), literal(std::move(literal)) {}

  std::unique_ptr<raw::Literal> literal;
};

struct SynthesizedConstant final : Constant {
  explicit SynthesizedConstant(std::unique_ptr<ConstantValue> value)
      : Constant(Kind::kSynthesized, SourceSpan()) {
    ResolveTo(std::move(value));
  }
};

struct BinaryOperatorConstant final : Constant {
  enum struct Operator { kOr };

  explicit BinaryOperatorConstant(std::unique_ptr<Constant> left_operand,
                                  std::unique_ptr<Constant> right_operand, Operator op,
                                  SourceSpan span)
      : Constant(Kind::kBinaryOperator, span),
        left_operand(std::move(left_operand)),
        right_operand(std::move(right_operand)),
        op(op) {}

  const std::unique_ptr<Constant> left_operand;
  const std::unique_ptr<Constant> right_operand;
  const Operator op;
};

}  // namespace flat
}  // namespace fidl

#endif  // TOOLS_FIDL_FIDLC_INCLUDE_FIDL_FLAT_VALUES_H_
