// 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/blobcat/blob_library.h"

#include <array>
#include <string>

#include "impeller/base/validation.h"
#include "impeller/blobcat/blob_flatbuffers.h"

namespace impeller {

constexpr BlobShaderType ToShaderType(fb::Stage stage) {
  switch (stage) {
    case fb::Stage::kVertex:
      return BlobShaderType::kVertex;
    case fb::Stage::kFragment:
      return BlobShaderType::kFragment;
    case fb::Stage::kCompute:
      return BlobShaderType::kCompute;
  }
  FML_UNREACHABLE();
}

BlobLibrary::BlobLibrary(std::shared_ptr<fml::Mapping> payload)
    : payload_(std::move(payload)) {
  if (!payload_ || payload_->GetMapping() == nullptr) {
    VALIDATION_LOG << "Blob mapping was absent.";
    return;
  }

  if (!fb::BlobLibraryBufferHasIdentifier(payload_->GetMapping())) {
    VALIDATION_LOG << "Invalid blob magic.";
    return;
  }

  auto blob_library = fb::GetBlobLibrary(payload_->GetMapping());
  if (!blob_library) {
    return;
  }

  if (auto items = blob_library->items()) {
    for (auto i = items->begin(), end = items->end(); i != end; i++) {
      BlobKey key;
      key.name = i->name()->str();
      key.type = ToShaderType(i->stage());
      blobs_[key] = std::make_shared<fml::NonOwnedMapping>(
          i->mapping()->Data(), i->mapping()->size(),
          [payload = payload_](auto, auto) {
            // The pointers are into the base payload. Instead of copying the
            // data, just hold onto the payload.
          });
    }
  }

  is_valid_ = true;
}

BlobLibrary::BlobLibrary(BlobLibrary&&) = default;

BlobLibrary::~BlobLibrary() = default;

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

size_t BlobLibrary::GetShaderCount() const {
  return blobs_.size();
}

std::shared_ptr<fml::Mapping> BlobLibrary::GetMapping(BlobShaderType type,
                                                      std::string name) const {
  BlobKey key;
  key.type = type;
  key.name = name;
  auto found = blobs_.find(key);
  return found == blobs_.end() ? nullptr : found->second;
}

size_t BlobLibrary::IterateAllBlobs(
    std::function<bool(BlobShaderType type,
                       const std::string& name,
                       const std::shared_ptr<fml::Mapping>& mapping)> callback)
    const {
  if (!IsValid() || !callback) {
    return 0u;
  }
  size_t count = 0u;
  for (const auto& blob : blobs_) {
    count++;
    if (!callback(blob.first.type, blob.first.name, blob.second)) {
      break;
    }
  }
  return count;
}

}  // namespace impeller
