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

#include "impeller/renderer/backend/metal/texture_mtl.h"
#include <memory>

#include "impeller/base/validation.h"
#include "impeller/core/texture_descriptor.h"

namespace impeller {

std::shared_ptr<Texture> WrapperMTL(TextureDescriptor desc,
                                    const void* mtl_texture,
                                    std::function<void()> deletion_proc) {
  return TextureMTL::Wrapper(desc, (__bridge id<MTLTexture>)mtl_texture,
                             std::move(deletion_proc));
}

TextureMTL::TextureMTL(TextureDescriptor p_desc,
                       const AcquireTextureProc& aquire_proc,
                       bool wrapped,
                       bool drawable)
    : Texture(p_desc), aquire_proc_(aquire_proc), is_drawable_(drawable) {
  const auto& desc = GetTextureDescriptor();

  if (!desc.IsValid() || !aquire_proc) {
    return;
  }

  if (desc.size != GetSize()) {
    VALIDATION_LOG << "The texture and its descriptor disagree about its size.";
    return;
  }

  is_wrapped_ = wrapped;
  is_valid_ = true;
}

std::shared_ptr<TextureMTL> TextureMTL::Wrapper(
    TextureDescriptor desc,
    id<MTLTexture> texture,
    std::function<void()> deletion_proc) {
  if (deletion_proc) {
    return std::shared_ptr<TextureMTL>(
        new TextureMTL(
            desc, [texture]() { return texture; }, true),
        [deletion_proc = std::move(deletion_proc)](TextureMTL* t) {
          deletion_proc();
          delete t;
        });
  }
  return std::shared_ptr<TextureMTL>(
      new TextureMTL(desc, [texture]() { return texture; }, true));
}

std::shared_ptr<TextureMTL> TextureMTL::Create(TextureDescriptor desc,
                                               id<MTLTexture> texture) {
  return std::make_shared<TextureMTL>(desc, [texture]() { return texture; });
}

TextureMTL::~TextureMTL() = default;

void TextureMTL::SetLabel(std::string_view label) {
  if (is_drawable_) {
    return;
  }
  [aquire_proc_() setLabel:@(label.data())];
}

// |Texture|
bool TextureMTL::OnSetContents(std::shared_ptr<const fml::Mapping> mapping,
                               size_t slice) {
  // Metal has no threading restrictions. So we can pass this data along to the
  // client rendering API immediately.
  return OnSetContents(mapping->GetMapping(), mapping->GetSize(), slice);
}

// |Texture|
bool TextureMTL::OnSetContents(const uint8_t* contents,
                               size_t length,
                               size_t slice) {
  if (!IsValid() || !contents || is_wrapped_ || is_drawable_) {
    return false;
  }

  const auto& desc = GetTextureDescriptor();

  // Out of bounds access.
  if (length != desc.GetByteSizeOfBaseMipLevel()) {
    return false;
  }

  const auto region =
      MTLRegionMake2D(0u, 0u, desc.size.width, desc.size.height);
  [aquire_proc_() replaceRegion:region                            //
                    mipmapLevel:0u                                //
                          slice:slice                             //
                      withBytes:contents                          //
                    bytesPerRow:desc.GetBytesPerRow()             //
                  bytesPerImage:desc.GetByteSizeOfBaseMipLevel()  //
  ];

  return true;
}

ISize TextureMTL::GetSize() const {
  if (is_drawable_) {
    return GetTextureDescriptor().size;
  }
  const auto& texture = aquire_proc_();
  return {static_cast<ISize::Type>(texture.width),
          static_cast<ISize::Type>(texture.height)};
}

id<MTLTexture> TextureMTL::GetMTLTexture() const {
  return aquire_proc_();
}

bool TextureMTL::IsValid() const {
  return is_valid_;
}

bool TextureMTL::IsWrapped() const {
  return is_wrapped_;
}

bool TextureMTL::IsDrawable() const {
  return is_drawable_;
}

bool TextureMTL::GenerateMipmap(id<MTLBlitCommandEncoder> encoder) {
  if (is_drawable_) {
    return false;
  }

  auto texture = aquire_proc_();
  if (!texture) {
    return false;
  }

  [encoder generateMipmapsForTexture:texture];
  mipmap_generated_ = true;

  return true;
}

}  // namespace impeller
