// 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 "flutter/fml/logging.h"
#include "include/core/SkImage.h"
#include "include/core/SkPicture.h"
#include "include/core/SkSerialProcs.h"
#include "include/core/SkStream.h"
#include "include/core/SkTypeface.h"

namespace flutter {

sk_sp<SkData> SerializeTypefaceWithoutData(SkTypeface* typeface, void* ctx) {
  return SkData::MakeEmpty();
}

sk_sp<SkData> SerializeTypefaceWithData(SkTypeface* typeface, void* ctx) {
  return typeface->serialize(SkTypeface::SerializeBehavior::kDoIncludeData);
}

sk_sp<SkTypeface> DeserializeTypefaceWithoutData(const void* data,
                                                 size_t length,
                                                 void* ctx) {
  return SkTypeface::MakeDefault();
}

struct ImageMetaData {
  int32_t width;
  int32_t height;
  uint32_t color_type;
  uint32_t alpha_type;
  bool has_color_space;
} __attribute__((packed));

sk_sp<SkData> SerializeImageWithoutData(SkImage* image, void* ctx) {
  auto info = image->imageInfo();
  SkDynamicMemoryWStream stream;

  ImageMetaData metadata = {info.width(), info.height(),
                            static_cast<uint32_t>(info.colorType()),
                            static_cast<uint32_t>(info.alphaType()),
                            static_cast<bool>(info.colorSpace())};
  stream.write(&metadata, sizeof(ImageMetaData));

  if (info.colorSpace()) {
    auto color_space_data = info.colorSpace()->serialize();
    FML_CHECK(color_space_data);
    SkMemoryStream color_space_stream(color_space_data);
    stream.writeStream(&color_space_stream, color_space_data->size());
  }

  return stream.detachAsData();
};

sk_sp<SkImage> DeserializeImageWithoutData(const void* data,
                                           size_t length,
                                           void* ctx) {
  FML_CHECK(length >= sizeof(ImageMetaData));
  auto metadata = static_cast<const ImageMetaData*>(data);
  sk_sp<SkColorSpace> color_space = nullptr;
  if (metadata->has_color_space) {
    color_space = SkColorSpace::Deserialize(
        static_cast<const uint8_t*>(data) + sizeof(ImageMetaData),
        length - sizeof(ImageMetaData));
  }

  auto image_size = SkISize::Make(metadata->width, metadata->height);
  auto info = SkImageInfo::Make(
      image_size, static_cast<SkColorType>(metadata->color_type),
      static_cast<SkAlphaType>(metadata->alpha_type), color_space);
  sk_sp<SkData> image_data =
      SkData::MakeUninitialized(image_size.width() * image_size.height() * 4);
  memset(image_data->writable_data(), 0x0f, image_data->size());
  sk_sp<SkImage> image =
      SkImage::MakeRasterData(info, image_data, image_size.width() * 4);

  return image;
};

}  // namespace flutter
