// Copyright 2021 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_SEM_STRUCT_H_
#define SRC_SEM_STRUCT_H_

#include <stdint.h>

#include <string>
#include <unordered_set>
#include <vector>

#include "src/ast/storage_class.h"
#include "src/ast/struct.h"
#include "src/sem/node.h"
#include "src/sem/type.h"
#include "src/symbol.h"

namespace tint {

// Forward declarations
namespace ast {
class StructMember;
}  // namespace ast

namespace sem {

// Forward declarations
class StructMember;
class Type;

/// A vector of StructMember pointers.
using StructMemberList = std::vector<const StructMember*>;

/// Metadata to capture how a structure is used in a shader module.
enum class PipelineStageUsage {
  kVertexInput,
  kVertexOutput,
  kFragmentInput,
  kFragmentOutput,
  kComputeInput,
  kComputeOutput,
};

/// Struct holds the semantic information for structures.
class Struct : public Castable<Struct, Type> {
 public:
  /// Constructor
  /// @param declaration the AST structure declaration
  /// @param name the name of the structure
  /// @param members the structure members
  /// @param align the byte alignment of the structure
  /// @param size the byte size of the structure
  /// @param size_no_padding size of the members without the end of structure
  /// alignment padding
  Struct(const ast::Struct* declaration,
         Symbol name,
         StructMemberList members,
         uint32_t align,
         uint32_t size,
         uint32_t size_no_padding);

  /// Destructor
  ~Struct() override;

  /// @returns the struct
  const ast::Struct* Declaration() const { return declaration_; }

  /// @returns the name of the structure
  Symbol Name() const { return name_; }

  /// @returns the members of the structure
  const StructMemberList& Members() const { return members_; }

  /// @param name the member name to look for
  /// @returns the member with the given name, or nullptr if it was not found.
  const StructMember* FindMember(Symbol name) const;

  /// @returns the byte alignment of the structure
  /// @note this may differ from the alignment of a structure member of this
  /// structure type, if the member is annotated with the `@align(n)`
  /// attribute.
  uint32_t Align() const override;

  /// @returns the byte size of the structure
  /// @note this may differ from the size of a structure member of this
  /// structure type, if the member is annotated with the `@size(n)`
  /// attribute.
  uint32_t Size() const override;

  /// @returns the byte size of the members without the end of structure
  /// alignment padding
  uint32_t SizeNoPadding() const { return size_no_padding_; }

  /// Adds the StorageClass usage to the structure.
  /// @param usage the storage usage
  void AddUsage(ast::StorageClass usage) {
    storage_class_usage_.emplace(usage);
  }

  /// @returns the set of storage class uses of this structure
  const std::unordered_set<ast::StorageClass>& StorageClassUsage() const {
    return storage_class_usage_;
  }

  /// @param usage the ast::StorageClass usage type to query
  /// @returns true iff this structure has been used as the given storage class
  bool UsedAs(ast::StorageClass usage) const {
    return storage_class_usage_.count(usage) > 0;
  }

  /// @returns true iff this structure has been used by storage class that's
  /// host-shareable.
  bool IsHostShareable() const {
    for (auto sc : storage_class_usage_) {
      if (ast::IsHostShareable(sc)) {
        return true;
      }
    }
    return false;
  }

  /// Adds the pipeline stage usage to the structure.
  /// @param usage the storage usage
  void AddUsage(PipelineStageUsage usage) {
    pipeline_stage_uses_.emplace(usage);
  }

  /// @returns the set of entry point uses of this structure
  const std::unordered_set<PipelineStageUsage>& PipelineStageUses() const {
    return pipeline_stage_uses_;
  }

  /// @returns the name for the type
  std::string type_name() const override;

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

  /// @param symbols the program's symbol table
  /// @returns a multiline string that describes the layout of this struct,
  /// including size and alignment information.
  std::string Layout(const tint::SymbolTable& symbols) const;

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

 private:
  uint64_t LargestMemberBaseAlignment(MemoryLayout mem_layout) const;

  ast::Struct const* const declaration_;
  const Symbol name_;
  const StructMemberList members_;
  const uint32_t align_;
  const uint32_t size_;
  const uint32_t size_no_padding_;
  std::unordered_set<ast::StorageClass> storage_class_usage_;
  std::unordered_set<PipelineStageUsage> pipeline_stage_uses_;
  bool constructible_;
};

/// StructMember holds the semantic information for structure members.
class StructMember : public Castable<StructMember, Node> {
 public:
  /// Constructor
  /// @param declaration the AST declaration node
  /// @param name the name of the structure
  /// @param type the type of the member
  /// @param index the index of the member in the structure
  /// @param offset the byte offset from the base of the structure
  /// @param align the byte alignment of the member
  /// @param size the byte size of the member
  StructMember(const ast::StructMember* declaration,
               Symbol name,
               sem::Type* type,
               uint32_t index,
               uint32_t offset,
               uint32_t align,
               uint32_t size);

  /// Destructor
  ~StructMember() override;

  /// @returns the AST declaration node
  const ast::StructMember* Declaration() const { return declaration_; }

  /// @returns the name of the structure
  Symbol Name() const { return name_; }

  /// @returns the type of the member
  sem::Type* Type() const { return type_; }

  /// @returns the member index
  uint32_t Index() const { return index_; }

  /// @returns byte offset from base of structure
  uint32_t Offset() const { return offset_; }

  /// @returns the alignment of the member in bytes
  uint32_t Align() const { return align_; }

  /// @returns byte size
  uint32_t Size() const { return size_; }

 private:
  const ast::StructMember* const declaration_;
  const Symbol name_;
  sem::Type* const type_;
  const uint32_t index_;
  const uint32_t offset_;
  const uint32_t align_;
  const uint32_t size_;
};

}  // namespace sem
}  // namespace tint

#endif  // SRC_SEM_STRUCT_H_
