// Copyright 2020 The Tint 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 SRC_TINT_SEM_TYPE_H_
#define SRC_TINT_SEM_TYPE_H_

#include <functional>
#include <string>

#include "src/tint/sem/node.h"

// Forward declarations
namespace tint {
class ProgramBuilder;
class SymbolTable;
}  // namespace tint

namespace tint::sem {

/// Supported memory layouts for calculating sizes
enum class MemoryLayout { kUniformBuffer, kStorageBuffer };

/// Base class for a type in the system
class Type : public Castable<Type, Node> {
  public:
    /// Move constructor
    Type(Type&&);
    ~Type() override;

    /// @returns a hash of the type.
    virtual size_t Hash() const = 0;

    /// @returns true if the this type is equal to the given type
    virtual bool Equals(const Type&) const = 0;

    /// @param symbols the program's symbol table
    /// @returns the name for this type that closely resembles how it would be
    /// declared in WGSL.
    virtual std::string FriendlyName(const SymbolTable& symbols) const = 0;

    /// @returns the inner most pointee type if this is a pointer, `this`
    /// otherwise
    const Type* UnwrapPtr() const;

    /// @returns the inner type if this is a reference, `this` otherwise
    const Type* UnwrapRef() const;

    /// @returns the size in bytes of the type. This may include tail padding.
    /// @note opaque types will return a size of 0.
    virtual uint32_t Size() const;

    /// @returns the alignment in bytes of the type. This may include tail
    /// padding.
    /// @note opaque types will return a size of 0.
    virtual uint32_t Align() const;

    /// @returns true if constructible as per
    /// https://gpuweb.github.io/gpuweb/wgsl/#constructible-types
    virtual bool IsConstructible() const;

    /// @returns true if this type is a scalar
    bool is_scalar() const;
    /// @returns true if this type is a scalar or an abstract numeric
    bool is_abstract_or_scalar() const;
    /// @returns true if this type is a numeric scalar
    bool is_numeric_scalar() const;
    /// @returns true if this type is a float scalar
    bool is_float_scalar() const;
    /// @returns true if this type is a float matrix
    bool is_float_matrix() const;
    /// @returns true if this type is a square float matrix
    bool is_square_float_matrix() const;
    /// @returns true if this type is a float vector
    bool is_float_vector() const;
    /// @returns true if this type is a float scalar or vector
    bool is_float_scalar_or_vector() const;
    /// @returns true if this type is a float scalar or vector or matrix
    bool is_float_scalar_or_vector_or_matrix() const;
    /// @returns true if this type is an integer scalar
    bool is_integer_scalar() const;
    /// @returns true if this type is a signed integer scalar
    bool is_signed_integer_scalar() const;
    /// @returns true if this type is an unsigned integer scalar
    bool is_unsigned_integer_scalar() const;
    /// @returns true if this type is a signed integer vector
    bool is_signed_integer_vector() const;
    /// @returns true if this type is an unsigned vector
    bool is_unsigned_integer_vector() const;
    /// @returns true if this type is an unsigned scalar or vector
    bool is_unsigned_scalar_or_vector() const;
    /// @returns true if this type is a signed scalar or vector
    bool is_signed_scalar_or_vector() const;
    /// @returns true if this type is an integer scalar or vector
    bool is_integer_scalar_or_vector() const;
    /// @returns true if this type is a boolean vector
    bool is_bool_vector() const;
    /// @returns true if this type is boolean scalar or vector
    bool is_bool_scalar_or_vector() const;
    /// @returns true if this type is a numeric vector
    bool is_numeric_vector() const;
    /// @returns true if this type is a vector of scalar type
    bool is_scalar_vector() const;
    /// @returns true if this type is a numeric scale or vector
    bool is_numeric_scalar_or_vector() const;
    /// @returns true if this type is a handle type
    bool is_handle() const;

    /// kNoConversion is returned from ConversionRank() when the implicit conversion is not
    /// permitted.
    static constexpr uint32_t kNoConversion = 0xffffffffu;

    /// ConversionRank returns the implicit conversion rank when attempting to convert `from` to
    /// `to`. Lower ranks are preferred over higher ranks.
    /// @param from the source type
    /// @param to the destination type
    /// @returns the rank value for converting from type `from` to type `to`, or #kNoConversion if
    /// the implicit conversion is not allowed.
    /// @see https://www.w3.org/TR/WGSL/#conversion-rank
    static uint32_t ConversionRank(const Type* from, const Type* to);

    /// @param ty the type to obtain the element type from
    /// @param count if not null, then this is assigned the number of child elements in the type.
    /// For example, the count of an `array<vec3<f32>, 5>` type would be 5.
    /// @returns
    ///   * `ty` if `ty` is an abstract or scalar
    ///   * the element type if `ty` is a vector or array
    ///   * the column type if `ty` is a matrix
    ///   * `nullptr` if `ty` is none of the above
    static const Type* ElementOf(const Type* ty, uint32_t* count = nullptr);

    /// @param ty the type to obtain the deepest element type from
    /// @param count if not null, then this is assigned the full number of most deeply nested
    /// elements in the type. For example, the count of an `array<vec3<f32>, 5>` type would be 15.
    /// @returns
    ///   * `ty` if `ty` is an abstract or scalar
    ///   * the element type if `ty` is a vector
    ///   * the matrix element type if `ty` is a matrix
    ///   * the deepest element type if `ty` is an array
    ///   * `nullptr` if `ty` is none of the above
    static const Type* DeepestElementOf(const Type* ty, uint32_t* count = nullptr);

    /// @param types a pointer to a list of `const Type*`.
    /// @param count the number of types in `types`.
    /// @returns the lowest-ranking type that all types in `types` can be implicitly converted to,
    /// or nullptr if there is no consistent common type across all types in `types`.
    /// @see https://www.w3.org/TR/WGSL/#conversion-rank
    static const sem::Type* Common(Type const* const* types, size_t count);

    /// @param types an initializer_list of `const Type*`.
    /// @returns the lowest-ranking type that all types in `types` can be implicitly converted to,
    /// or nullptr if there is no consistent common type across all types in `types`.
    /// @see https://www.w3.org/TR/WGSL/#conversion-rank
    static const sem::Type* Common(std::initializer_list<const Type*> types) {
        return Common(types.begin(), types.size());
    }

  protected:
    Type();
};

}  // namespace tint::sem

namespace std {

/// std::hash specialization for tint::sem::Type
template <>
struct hash<tint::sem::Type> {
    /// @param type the type to obtain a hash from
    /// @returns the hash of the semantic type
    size_t operator()(const tint::sem::Type& type) const { return type.Hash(); }
};

/// std::equal_to specialization for tint::sem::Type
template <>
struct equal_to<tint::sem::Type> {
    /// @param a the first type to compare
    /// @param b the second type to compare
    /// @returns true if the two types are equal
    bool operator()(const tint::sem::Type& a, const tint::sem::Type& b) const {
        return a.Equals(b);
    }
};

}  // namespace std

#endif  // SRC_TINT_SEM_TYPE_H_
