// 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/transform/decompose_strided_matrix.h"

#include <unordered_map>
#include <utility>
#include <vector>

#include "src/program_builder.h"
#include "src/sem/expression.h"
#include "src/sem/member_accessor_expression.h"
#include "src/transform/simplify_pointers.h"
#include "src/utils/hash.h"
#include "src/utils/map.h"

TINT_INSTANTIATE_TYPEINFO(tint::transform::DecomposeStridedMatrix);

namespace tint {
namespace transform {
namespace {

/// MatrixInfo describes a matrix member with a custom stride
struct MatrixInfo {
  /// The stride in bytes between columns of the matrix
  uint32_t stride = 0;
  /// The type of the matrix
  const sem::Matrix* matrix = nullptr;

  /// @returns a new ast::Array that holds an vector column for each row of the
  /// matrix.
  const ast::Array* array(ProgramBuilder* b) const {
    return b->ty.array(b->ty.vec<ProgramBuilder::f32>(matrix->rows()),
                       matrix->columns(), stride);
  }

  /// Equality operator
  bool operator==(const MatrixInfo& info) const {
    return stride == info.stride && matrix == info.matrix;
  }
  /// Hash function
  struct Hasher {
    size_t operator()(const MatrixInfo& t) const {
      return utils::Hash(t.stride, t.matrix);
    }
  };
};

/// Return type of the callback function of GatherCustomStrideMatrixMembers
enum GatherResult { kContinue, kStop };

/// GatherCustomStrideMatrixMembers scans `program` for all matrix members of
/// storage and uniform structs, which are of a matrix type, and have a custom
/// matrix stride attribute. For each matrix member found, `callback` is called.
/// `callback` is a function with the signature:
///      GatherResult(const sem::StructMember* member,
///                   sem::Matrix* matrix,
///                   uint32_t stride)
/// If `callback` return GatherResult::kStop, then the scanning will immediately
/// terminate, and GatherCustomStrideMatrixMembers() will return, otherwise
/// scanning will continue.
template <typename F>
void GatherCustomStrideMatrixMembers(const Program* program, F&& callback) {
  for (auto* node : program->ASTNodes().Objects()) {
    if (auto* str = node->As<ast::Struct>()) {
      auto* str_ty = program->Sem().Get(str);
      if (!str_ty->UsedAs(ast::StorageClass::kUniform) &&
          !str_ty->UsedAs(ast::StorageClass::kStorage)) {
        continue;
      }
      for (auto* member : str_ty->Members()) {
        auto* matrix = member->Type()->As<sem::Matrix>();
        if (!matrix) {
          continue;
        }
        auto* deco = ast::GetDecoration<ast::StrideDecoration>(
            member->Declaration()->decorations);
        if (!deco) {
          continue;
        }
        uint32_t stride = deco->stride;
        if (matrix->ColumnStride() == stride) {
          continue;
        }
        if (callback(member, matrix, stride) == GatherResult::kStop) {
          return;
        }
      }
    }
  }
}

}  // namespace

DecomposeStridedMatrix::DecomposeStridedMatrix() = default;

DecomposeStridedMatrix::~DecomposeStridedMatrix() = default;

bool DecomposeStridedMatrix::ShouldRun(const Program* program,
                                       const DataMap&) const {
  bool should_run = false;
  GatherCustomStrideMatrixMembers(
      program, [&](const sem::StructMember*, sem::Matrix*, uint32_t) {
        should_run = true;
        return GatherResult::kStop;
      });
  return should_run;
}

void DecomposeStridedMatrix::Run(CloneContext& ctx,
                                 const DataMap&,
                                 DataMap&) const {
  // Scan the program for all storage and uniform structure matrix members with
  // a custom stride attribute. Replace these matrices with an equivalent array,
  // and populate the `decomposed` map with the members that have been replaced.
  std::unordered_map<const ast::StructMember*, MatrixInfo> decomposed;
  GatherCustomStrideMatrixMembers(
      ctx.src, [&](const sem::StructMember* member, sem::Matrix* matrix,
                   uint32_t stride) {
        // We've got ourselves a struct member of a matrix type with a custom
        // stride. Replace this with an array of column vectors.
        MatrixInfo info{stride, matrix};
        auto* replacement = ctx.dst->Member(
            member->Offset(), ctx.Clone(member->Name()), info.array(ctx.dst));
        ctx.Replace(member->Declaration(), replacement);
        decomposed.emplace(member->Declaration(), info);
        return GatherResult::kContinue;
      });

  // For all expressions where a single matrix column vector was indexed, we can
  // preserve these without calling conversion functions.
  // Example:
  //   ssbo.mat[2] -> ssbo.mat[2]
  ctx.ReplaceAll([&](const ast::IndexAccessorExpression* expr)
                     -> const ast::IndexAccessorExpression* {
    if (auto* access =
            ctx.src->Sem().Get<sem::StructMemberAccess>(expr->object)) {
      auto it = decomposed.find(access->Member()->Declaration());
      if (it != decomposed.end()) {
        auto* obj = ctx.CloneWithoutTransform(expr->object);
        auto* idx = ctx.Clone(expr->index);
        return ctx.dst->IndexAccessor(obj, idx);
      }
    }
    return nullptr;
  });

  // For all struct member accesses to the matrix on the LHS of an assignment,
  // we need to convert the matrix to the array before assigning to the
  // structure.
  // Example:
  //   ssbo.mat = mat_to_arr(m)
  std::unordered_map<MatrixInfo, Symbol, MatrixInfo::Hasher> mat_to_arr;
  ctx.ReplaceAll([&](const ast::AssignmentStatement* stmt)
                     -> const ast::Statement* {
    if (auto* access = ctx.src->Sem().Get<sem::StructMemberAccess>(stmt->lhs)) {
      auto it = decomposed.find(access->Member()->Declaration());
      if (it == decomposed.end()) {
        return nullptr;
      }
      MatrixInfo info = it->second;
      auto fn = utils::GetOrCreate(mat_to_arr, info, [&] {
        auto name = ctx.dst->Symbols().New(
            "mat" + std::to_string(info.matrix->columns()) + "x" +
            std::to_string(info.matrix->rows()) + "_stride_" +
            std::to_string(info.stride) + "_to_arr");

        auto matrix = [&] { return CreateASTTypeFor(ctx, info.matrix); };
        auto array = [&] { return info.array(ctx.dst); };

        auto mat = ctx.dst->Sym("mat");
        ast::ExpressionList columns(info.matrix->columns());
        for (uint32_t i = 0; i < static_cast<uint32_t>(columns.size()); i++) {
          columns[i] = ctx.dst->IndexAccessor(mat, i);
        }
        ctx.dst->Func(name,
                      {
                          ctx.dst->Param(mat, matrix()),
                      },
                      array(),
                      {
                          ctx.dst->Return(ctx.dst->Construct(array(), columns)),
                      });
        return name;
      });
      auto* lhs = ctx.CloneWithoutTransform(stmt->lhs);
      auto* rhs = ctx.dst->Call(fn, ctx.Clone(stmt->rhs));
      return ctx.dst->Assign(lhs, rhs);
    }
    return nullptr;
  });

  // For all other struct member accesses, we need to convert the array to the
  // matrix type. Example:
  //   m = arr_to_mat(ssbo.mat)
  std::unordered_map<MatrixInfo, Symbol, MatrixInfo::Hasher> arr_to_mat;
  ctx.ReplaceAll(
      [&](const ast::MemberAccessorExpression* expr) -> const ast::Expression* {
        if (auto* access = ctx.src->Sem().Get<sem::StructMemberAccess>(expr)) {
          auto it = decomposed.find(access->Member()->Declaration());
          if (it == decomposed.end()) {
            return nullptr;
          }
          MatrixInfo info = it->second;
          auto fn = utils::GetOrCreate(arr_to_mat, info, [&] {
            auto name = ctx.dst->Symbols().New(
                "arr_to_mat" + std::to_string(info.matrix->columns()) + "x" +
                std::to_string(info.matrix->rows()) + "_stride_" +
                std::to_string(info.stride));

            auto matrix = [&] { return CreateASTTypeFor(ctx, info.matrix); };
            auto array = [&] { return info.array(ctx.dst); };

            auto arr = ctx.dst->Sym("arr");
            ast::ExpressionList columns(info.matrix->columns());
            for (uint32_t i = 0; i < static_cast<uint32_t>(columns.size());
                 i++) {
              columns[i] = ctx.dst->IndexAccessor(arr, i);
            }
            ctx.dst->Func(
                name,
                {
                    ctx.dst->Param(arr, array()),
                },
                matrix(),
                {
                    ctx.dst->Return(ctx.dst->Construct(matrix(), columns)),
                });
            return name;
          });
          return ctx.dst->Call(fn, ctx.CloneWithoutTransform(expr));
        }
        return nullptr;
      });

  ctx.Clone();
}

}  // namespace transform
}  // namespace tint
