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

namespace impeller {

BlobLibrary::BlobLibrary(std::shared_ptr<fml::Mapping> mapping)
    : mapping_(std::move(mapping)) {
  if (!mapping_ || mapping_->GetMapping() == nullptr) {
    FML_LOG(ERROR) << "Invalid mapping.";
    return;
  }

  BlobHeader header;
  std::vector<Blob> blobs;

  size_t offset = 0u;

  // Read the header.
  {
    const size_t read_size = sizeof(BlobHeader);
    if (mapping_->GetSize() < offset + read_size) {
      return;
    }
    std::memcpy(&header, mapping_->GetMapping() + offset, read_size);
    offset += read_size;

    // Validate the header.
    if (header.magic != kBlobCatMagic) {
      FML_LOG(ERROR) << "Invalid blob magic.";
      return;
    }

    blobs.resize(header.blob_count);
  }

  // Read the blob descriptions.
  {
    const size_t read_size = sizeof(Blob) * header.blob_count;
    ::memcpy(blobs.data(), mapping_->GetMapping() + offset, read_size);
    offset += read_size;
  }

  // Read the blobs.
  {
    for (size_t i = 0; i < header.blob_count; i++) {
      const auto& blob = blobs[i];

      BlobKey key;
      key.type = blob.type;
      key.name = std::string{reinterpret_cast<const char*>(blob.name)};
      auto mapping = std::make_shared<fml::NonOwnedMapping>(
          mapping_->GetMapping() + blob.offset,  // offset
          blob.length,                           // length
          [mapping = mapping_](const uint8_t* data, size_t size) {}
          // release proc
      );

      auto inserted = blobs_.insert({key, mapping});
      if (!inserted.second) {
        FML_LOG(ERROR) << "Shader library had duplicate shader named "
                       << key.name;
        return;
      }
    }
  }

  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(Blob::ShaderType 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(Blob::ShaderType 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
