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

#define FML_USED_ON_EMBEDDER

#include <limits>
#include <utility>

#include "flutter/shell/platform/embedder/tests/embedder_test_backingstore_producer.h"
#include "flutter/shell/platform/embedder/tests/embedder_unittests_util.h"

namespace flutter {
namespace testing {

sk_sp<SkSurface> CreateRenderSurface(const FlutterLayer& layer,
                                     GrDirectContext* context) {
  const auto image_info =
      SkImageInfo::MakeN32Premul(layer.size.width, layer.size.height);
  auto surface = context ? SkSurface::MakeRenderTarget(
                               context,                   // context
                               SkBudgeted::kNo,           // budgeted
                               image_info,                // image info
                               1,                         // sample count
                               kTopLeft_GrSurfaceOrigin,  // surface origin
                               nullptr,                   // surface properties
                               false                      // mipmaps

                               )
                         : SkSurface::MakeRaster(image_info);
  FML_CHECK(surface != nullptr);
  return surface;
}

// Normalizes the color-space, color-type and alpha-type for comparison.
static sk_sp<SkData> NormalizeImage(const sk_sp<SkImage>& image) {
  // To avoid clipping, convert to a very wide gamut, and a high bit depth.
  sk_sp<SkColorSpace> norm_colorspace = SkColorSpace::MakeRGB(
      SkNamedTransferFn::kRec2020, SkNamedGamut::kRec2020);
  SkImageInfo norm_image_info =
      SkImageInfo::Make(image->width(), image->height(),
                        SkColorType::kR16G16B16A16_unorm_SkColorType,
                        SkAlphaType::kUnpremul_SkAlphaType, norm_colorspace);
  size_t row_bytes = norm_image_info.minRowBytes();
  size_t size = norm_image_info.computeByteSize(row_bytes);
  sk_sp<SkData> data = SkData::MakeUninitialized(size);
  if (!data) {
    FML_CHECK(false) << "Unable to allocate data.";
  }

  bool success = image->readPixels(norm_image_info, data->writable_data(),
                                   row_bytes, 0, 0);
  if (!success) {
    FML_CHECK(false) << "Unable to read pixels.";
  }

  return data;
}

bool RasterImagesAreSame(const sk_sp<SkImage>& a, const sk_sp<SkImage>& b) {
  if (!a || !b) {
    return false;
  }

  FML_CHECK(!a->isTextureBacked());
  FML_CHECK(!b->isTextureBacked());

  sk_sp<SkData> normalized_a = NormalizeImage(a);
  sk_sp<SkData> normalized_b = NormalizeImage(b);

  return normalized_a->equals(normalized_b.get());
}

std::string FixtureNameForBackend(EmbedderTestContextType backend,
                                  const std::string& name) {
  switch (backend) {
    case EmbedderTestContextType::kVulkanContext:
      return "vk_" + name;
    default:
      return name;
  }
}

EmbedderTestBackingStoreProducer::RenderTargetType GetRenderTargetFromBackend(
    EmbedderTestContextType backend,
    bool opengl_framebuffer) {
  switch (backend) {
    case EmbedderTestContextType::kVulkanContext:
      return EmbedderTestBackingStoreProducer::RenderTargetType::kVulkanImage;
    case EmbedderTestContextType::kOpenGLContext:
      if (opengl_framebuffer) {
        return EmbedderTestBackingStoreProducer::RenderTargetType::
            kOpenGLFramebuffer;
      }
      return EmbedderTestBackingStoreProducer::RenderTargetType::kOpenGLTexture;
    case EmbedderTestContextType::kMetalContext:
      return EmbedderTestBackingStoreProducer::RenderTargetType::kMetalTexture;
    case EmbedderTestContextType::kSoftwareContext:
      return EmbedderTestBackingStoreProducer::RenderTargetType::
          kSoftwareBuffer;
  }
}

void ConfigureBackingStore(FlutterBackingStore& backing_store,
                           EmbedderTestContextType backend,
                           bool opengl_framebuffer) {
  switch (backend) {
    case EmbedderTestContextType::kVulkanContext:
      backing_store.type = kFlutterBackingStoreTypeVulkan;
      break;
    case EmbedderTestContextType::kOpenGLContext:
      if (opengl_framebuffer) {
        backing_store.type = kFlutterBackingStoreTypeOpenGL;
        backing_store.open_gl.type = kFlutterOpenGLTargetTypeFramebuffer;
      } else {
        backing_store.type = kFlutterBackingStoreTypeOpenGL;
        backing_store.open_gl.type = kFlutterOpenGLTargetTypeTexture;
      }
      break;
    case EmbedderTestContextType::kMetalContext:
      backing_store.type = kFlutterBackingStoreTypeMetal;
      break;
    case EmbedderTestContextType::kSoftwareContext:
      backing_store.type = kFlutterBackingStoreTypeSoftware;
      break;
  }
}

bool WriteImageToDisk(const fml::UniqueFD& directory,
                      const std::string& name,
                      const sk_sp<SkImage>& image) {
  if (!image) {
    return false;
  }

  auto data = image->encodeToData();

  if (!data) {
    return false;
  }

  fml::NonOwnedMapping mapping(static_cast<const uint8_t*>(data->data()),
                               data->size());
  return WriteAtomically(directory, name.c_str(), mapping);
}

bool ImageMatchesFixture(const std::string& fixture_file_name,
                         const sk_sp<SkImage>& scene_image) {
  fml::FileMapping fixture_image_mapping(OpenFixture(fixture_file_name));

  FML_CHECK(fixture_image_mapping.GetSize() != 0u)
      << "Could not find fixture: " << fixture_file_name;

  auto encoded_image = SkData::MakeWithoutCopy(
      fixture_image_mapping.GetMapping(), fixture_image_mapping.GetSize());
  auto fixture_image =
      SkImage::MakeFromEncoded(std::move(encoded_image))->makeRasterImage();

  FML_CHECK(fixture_image) << "Could not create image from fixture: "
                           << fixture_file_name;

  FML_CHECK(scene_image) << "Invalid scene image.";

  auto scene_image_subset = scene_image->makeSubset(
      SkIRect::MakeWH(fixture_image->width(), fixture_image->height()));

  FML_CHECK(scene_image_subset)
      << "Could not create image subset for fixture comparison: "
      << scene_image_subset;

  const auto images_are_same =
      RasterImagesAreSame(scene_image_subset, fixture_image);

  // If the images are not the same, this predicate is going to indicate test
  // failure. Dump both the actual image and the expectation to disk to the
  // test author can figure out what went wrong.
  if (!images_are_same) {
    const auto fixtures_path = GetFixturesPath();

    const auto actual_file_name = "actual_" + fixture_file_name;
    const auto expect_file_name = "expectation_" + fixture_file_name;

    auto fixtures_fd = OpenFixturesDirectory();

    FML_CHECK(
        WriteImageToDisk(fixtures_fd, actual_file_name, scene_image_subset))
        << "Could not write file to disk: " << actual_file_name;

    FML_CHECK(WriteImageToDisk(fixtures_fd, expect_file_name, fixture_image))
        << "Could not write file to disk: " << expect_file_name;

    FML_LOG(ERROR) << "Image did not match expectation." << std::endl
                   << "Expected:"
                   << fml::paths::JoinPaths({fixtures_path, expect_file_name})
                   << std::endl
                   << "Got:"
                   << fml::paths::JoinPaths({fixtures_path, actual_file_name})
                   << std::endl;
  }
  return images_are_same;
}

bool ImageMatchesFixture(const std::string& fixture_file_name,
                         std::future<sk_sp<SkImage>>& scene_image) {
  return ImageMatchesFixture(fixture_file_name, scene_image.get());
}

bool SurfacePixelDataMatchesBytes(SkSurface* surface,
                                  const std::vector<uint8_t>& bytes) {
  SkPixmap pixmap;
  auto ok = surface->peekPixels(&pixmap);
  if (!ok) {
    return false;
  }

  auto matches = (pixmap.rowBytes() == bytes.size()) &&
                 (memcmp(bytes.data(), pixmap.addr(), bytes.size()) == 0);

  if (!matches) {
    FML_LOG(ERROR) << "SkImage pixel data didn't match bytes.";

    {
      const uint8_t* addr = static_cast<const uint8_t*>(pixmap.addr());
      std::stringstream stream;
      for (size_t i = 0; i < pixmap.computeByteSize(); ++i) {
        stream << "0x" << std::setfill('0') << std::setw(2) << std::uppercase
               << std::hex << static_cast<int>(addr[i]);
        if (i != pixmap.computeByteSize() - 1) {
          stream << ", ";
        }
      }
      FML_LOG(ERROR) << "  Actual:   " << stream.str();
    }
    {
      std::stringstream stream;
      for (auto b = bytes.begin(); b != bytes.end(); ++b) {
        stream << "0x" << std::setfill('0') << std::setw(2) << std::uppercase
               << std::hex << static_cast<int>(*b);
        if (b != bytes.end() - 1) {
          stream << ", ";
        }
      }
      FML_LOG(ERROR) << "  Expected: " << stream.str();
    }
  }

  return matches;
}

bool SurfacePixelDataMatchesBytes(std::future<SkSurface*>& surface_future,
                                  const std::vector<uint8_t>& bytes) {
  return SurfacePixelDataMatchesBytes(surface_future.get(), bytes);
}

void FilterMutationsByType(
    const FlutterPlatformViewMutation** mutations,
    size_t count,
    FlutterPlatformViewMutationType type,
    const std::function<void(const FlutterPlatformViewMutation& mutation)>&
        handler) {
  if (mutations == nullptr) {
    return;
  }

  for (size_t i = 0; i < count; ++i) {
    const FlutterPlatformViewMutation* mutation = mutations[i];
    if (mutation->type != type) {
      continue;
    }

    handler(*mutation);
  }
}

void FilterMutationsByType(
    const FlutterPlatformView* view,
    FlutterPlatformViewMutationType type,
    const std::function<void(const FlutterPlatformViewMutation& mutation)>&
        handler) {
  return FilterMutationsByType(view->mutations, view->mutations_count, type,
                               handler);
}

SkMatrix GetTotalMutationTransformationMatrix(
    const FlutterPlatformViewMutation** mutations,
    size_t count) {
  SkMatrix collected;

  FilterMutationsByType(
      mutations, count, kFlutterPlatformViewMutationTypeTransformation,
      [&](const auto& mutation) {
        collected.preConcat(SkMatrixMake(mutation.transformation));
      });

  return collected;
}

SkMatrix GetTotalMutationTransformationMatrix(const FlutterPlatformView* view) {
  return GetTotalMutationTransformationMatrix(view->mutations,
                                              view->mutations_count);
}

}  // namespace testing
}  // namespace flutter
