// 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.

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

#include <cmath>
#include <iomanip>
#include <string>
#include <utility>

#include "src/tint/ast/struct_member.h"
#include "src/tint/symbol_table.h"
#include "src/tint/utils/hash.h"

TINT_INSTANTIATE_TYPEINFO(tint::sem::Struct);
TINT_INSTANTIATE_TYPEINFO(tint::sem::StructMember);

namespace tint {
namespace sem {

Struct::Struct(const ast::Struct* declaration,
               Symbol name,
               StructMemberList members,
               uint32_t align,
               uint32_t size,
               uint32_t size_no_padding)
    : declaration_(declaration),
      name_(name),
      members_(std::move(members)),
      align_(align),
      size_(size),
      size_no_padding_(size_no_padding) {
  constructible_ = true;
  for (auto* member : members_) {
    if (!member->Type()->IsConstructible()) {
      constructible_ = false;
      break;
    }
  }
}

Struct::~Struct() = default;

size_t Struct::Hash() const {
  return utils::Hash(TypeInfo::Of<Struct>().full_hashcode, name_);
}

bool Struct::Equals(const sem::Type& other) const {
  if (auto* o = other.As<Struct>()) {
    return o->name_ == name_;
  }
  return false;
}

const StructMember* Struct::FindMember(Symbol name) const {
  for (auto* member : members_) {
    if (member->Declaration()->symbol == name) {
      return member;
    }
  }
  return nullptr;
}

uint32_t Struct::Align() const {
  return align_;
}

uint32_t Struct::Size() const {
  return size_;
}

std::string Struct::FriendlyName(const SymbolTable& symbols) const {
  return symbols.NameFor(name_);
}

std::string Struct::Layout(const tint::SymbolTable& symbols) const {
  std::stringstream ss;

  auto member_name_of = [&](const sem::StructMember* sm) {
    return symbols.NameFor(sm->Declaration()->symbol);
  };

  if (Members().empty()) {
    return {};
  }
  const auto* const last_member = Members().back();
  const uint32_t last_member_struct_padding_offset =
      last_member->Offset() + last_member->Size();

  // Compute max widths to align output
  const auto offset_w =
      static_cast<int>(::log10(last_member_struct_padding_offset)) + 1;
  const auto size_w = static_cast<int>(::log10(Size())) + 1;
  const auto align_w = static_cast<int>(::log10(Align())) + 1;

  auto print_struct_begin_line = [&](size_t align, size_t size,
                                     std::string struct_name) {
    ss << "/*          " << std::setw(offset_w) << " "
       << "align(" << std::setw(align_w) << align << ") size("
       << std::setw(size_w) << size << ") */ struct " << struct_name << " {\n";
  };

  auto print_struct_end_line = [&]() {
    ss << "/*                         "
       << std::setw(offset_w + size_w + align_w) << " "
       << "*/ };";
  };

  auto print_member_line = [&](size_t offset, size_t align, size_t size,
                               std::string s) {
    ss << "/* offset(" << std::setw(offset_w) << offset << ") align("
       << std::setw(align_w) << align << ") size(" << std::setw(size_w) << size
       << ") */   " << s << ";\n";
  };

  print_struct_begin_line(Align(), Size(), UnwrapRef()->FriendlyName(symbols));

  for (size_t i = 0; i < Members().size(); ++i) {
    auto* const m = Members()[i];

    // Output field alignment padding, if any
    auto* const prev_member = (i == 0) ? nullptr : Members()[i - 1];
    if (prev_member) {
      uint32_t padding =
          m->Offset() - (prev_member->Offset() + prev_member->Size());
      if (padding > 0) {
        size_t padding_offset = m->Offset() - padding;
        print_member_line(padding_offset, 1, padding,
                          "// -- implicit field alignment padding --");
      }
    }

    // Output member
    std::string member_name = member_name_of(m);
    print_member_line(
        m->Offset(), m->Align(), m->Size(),
        member_name + " : " + m->Type()->UnwrapRef()->FriendlyName(symbols));
  }

  // Output struct size padding, if any
  uint32_t struct_padding = Size() - last_member_struct_padding_offset;
  if (struct_padding > 0) {
    print_member_line(last_member_struct_padding_offset, 1, struct_padding,
                      "// -- implicit struct size padding --");
  }

  print_struct_end_line();

  return ss.str();
}

bool Struct::IsConstructible() const {
  return constructible_;
}

StructMember::StructMember(const ast::StructMember* declaration,
                           Symbol name,
                           sem::Type* type,
                           uint32_t index,
                           uint32_t offset,
                           uint32_t align,
                           uint32_t size)
    : declaration_(declaration),
      name_(name),
      type_(type),
      index_(index),
      offset_(offset),
      align_(align),
      size_(size) {}

StructMember::~StructMember() = default;

}  // namespace sem
}  // namespace tint
