// Copyright 2017 The Chromium 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 "components/printing/service/pdf_compositor_impl.h"

#include <tuple>

#include "base/logging.h"
#include "base/memory/shared_memory_handle.h"
#include "components/printing/service/public/cpp/pdf_service_mojo_types.h"
#include "components/printing/service/public/cpp/pdf_service_mojo_utils.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "printing/common/pdf_metafile_utils.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkDocument.h"
#include "third_party/skia/include/core/SkSerialProcs.h"
#include "third_party/skia/src/utils/SkMultiPictureDocument.h"

namespace printing {

PdfCompositorImpl::PdfCompositorImpl(
    const std::string& creator,
    std::unique_ptr<service_manager::ServiceContextRef> service_ref)
    : service_ref_(std::move(service_ref)), creator_(creator) {}

PdfCompositorImpl::~PdfCompositorImpl() = default;

void PdfCompositorImpl::AddSubframeContent(
    uint64_t frame_guid,
    mojo::ScopedSharedBufferHandle serialized_content,
    const ContentToFrameMap& subframe_content_map) {
  // Add this frame and its serialized content.
  DCHECK(!base::ContainsKey(frame_info_map_, frame_guid));
  auto& frame_info =
      frame_info_map_.emplace(frame_guid, std::make_unique<FrameInfo>())
          .first->second;
  frame_info->serialized_content =
      GetShmFromMojoHandle(std::move(serialized_content));

  // Copy the subframe content information.
  frame_info->subframe_content_map = subframe_content_map;

  // If there is no request, we do nothing more.
  // Otherwise, we need to check whether any request actually waits on this
  // frame content.
  if (requests_.empty())
    return;

  // Get the pending list which is a list of subframes this frame needs
  // but are still unavailable.
  std::vector<uint64_t> pending_subframes;
  for (auto& subframe_content : subframe_content_map) {
    auto subframe_guid = subframe_content.second;
    if (!base::ContainsKey(frame_info_map_, subframe_guid))
      pending_subframes.push_back(subframe_guid);
  }

  // Check for each request's pending list.
  for (auto it = requests_.begin(); it != requests_.end();) {
    auto& request = *it;
    // If the request needs this frame, we can remove the dependency, but
    // update with this frame's pending list.
    auto& pending_list = request->pending_subframes;
    if (pending_list.erase(frame_guid)) {
      std::copy(pending_subframes.begin(), pending_subframes.end(),
                std::inserter(pending_list, pending_list.end()));
      if (pending_list.empty()) {
        // If the request isn't waiting on any subframes then it is ready.
        // Fulfill the request now.
        FulfillRequest(request->frame_guid, request->page_number,
                       std::move(request->serialized_content),
                       request->subframe_content_map,
                       std::move(request->callback));
        it = requests_.erase(it);
        continue;
      }
    }
    // If the request still has pending frames, keep waiting.
    ++it;
  }
}

void PdfCompositorImpl::CompositePageToPdf(
    uint64_t frame_guid,
    uint32_t page_num,
    mojo::ScopedSharedBufferHandle serialized_content,
    const ContentToFrameMap& subframe_content_map,
    mojom::PdfCompositor::CompositePageToPdfCallback callback) {
  HandleCompositionRequest(frame_guid, page_num, std::move(serialized_content),
                           subframe_content_map, std::move(callback));
}

void PdfCompositorImpl::CompositeDocumentToPdf(
    uint64_t frame_guid,
    mojo::ScopedSharedBufferHandle serialized_content,
    const ContentToFrameMap& subframe_content_map,
    mojom::PdfCompositor::CompositeDocumentToPdfCallback callback) {
  HandleCompositionRequest(frame_guid, base::nullopt,
                           std::move(serialized_content), subframe_content_map,
                           std::move(callback));
}

bool PdfCompositorImpl::IsReadyToComposite(
    uint64_t frame_guid,
    const ContentToFrameMap& subframe_content_map,
    base::flat_set<uint64_t>* pending_subframes) {
  pending_subframes->clear();
  base::flat_set<uint64_t> visited_frames;
  visited_frames.insert(frame_guid);
  CheckFramesForReadiness(frame_guid, subframe_content_map, pending_subframes,
                          &visited_frames);
  return pending_subframes->empty();
}

void PdfCompositorImpl::CheckFramesForReadiness(
    uint64_t frame_guid,
    const ContentToFrameMap& subframe_content_map,
    base::flat_set<uint64_t>* pending_subframes,
    base::flat_set<uint64_t>* visited) {
  for (auto& subframe_content : subframe_content_map) {
    auto subframe_guid = subframe_content.second;
    // If this frame has been checked, skip it.
    auto result = visited->insert(subframe_guid);
    if (!result.second)
      continue;

    auto iter = frame_info_map_.find(subframe_guid);
    if (iter == frame_info_map_.end()) {
      pending_subframes->insert(subframe_guid);
    } else {
      CheckFramesForReadiness(subframe_guid, iter->second->subframe_content_map,
                              pending_subframes, visited);
    }
  }
}

void PdfCompositorImpl::HandleCompositionRequest(
    uint64_t frame_guid,
    base::Optional<uint32_t> page_num,
    mojo::ScopedSharedBufferHandle serialized_content,
    const ContentToFrameMap& subframe_content_map,
    CompositeToPdfCallback callback) {
  base::flat_set<uint64_t> pending_subframes;
  if (IsReadyToComposite(frame_guid, subframe_content_map,
                         &pending_subframes)) {
    FulfillRequest(frame_guid, page_num,
                   GetShmFromMojoHandle(std::move(serialized_content)),
                   subframe_content_map, std::move(callback));
    return;
  }

  // When it is not ready yet, keep its information and
  // wait until all dependent subframes are ready.
  auto iter = frame_info_map_.find(frame_guid);
  if (iter == frame_info_map_.end())
    frame_info_map_[frame_guid] = std::make_unique<FrameInfo>();

  requests_.push_back(std::make_unique<RequestInfo>(
      frame_guid, page_num, GetShmFromMojoHandle(std::move(serialized_content)),
      subframe_content_map, std::move(pending_subframes), std::move(callback)));
}

mojom::PdfCompositor::Status PdfCompositorImpl::CompositeToPdf(
    uint64_t frame_guid,
    base::Optional<uint32_t> page_num,
    std::unique_ptr<base::SharedMemory> shared_mem,
    const ContentToFrameMap& subframe_content_map,
    mojo::ScopedSharedBufferHandle* handle) {
  DeserializationContext subframes =
      GetDeserializationContext(subframe_content_map);

  // Read in content and convert it into pdf.
  SkMemoryStream stream(shared_mem->memory(), shared_mem->mapped_size());
  int page_count = SkMultiPictureDocumentReadPageCount(&stream);
  if (!page_count) {
    DLOG(ERROR) << "CompositeToPdf: No page is read.";
    return mojom::PdfCompositor::Status::CONTENT_FORMAT_ERROR;
  }

  std::vector<SkDocumentPage> pages(page_count);
  // TODO(weili): Change the default functions to actual implementation.
  SkDeserialProcs procs;
  if (!SkMultiPictureDocumentRead(&stream, pages.data(), page_count, &procs)) {
    DLOG(ERROR) << "CompositeToPdf: Page reading failed.";
    return mojom::PdfCompositor::Status::CONTENT_FORMAT_ERROR;
  }

  SkDynamicMemoryWStream wstream;
  sk_sp<SkDocument> doc = MakePdfDocument(creator_, &wstream);

  for (const auto& page : pages) {
    SkCanvas* canvas = doc->beginPage(page.fSize.width(), page.fSize.height());
    canvas->drawPicture(page.fPicture);
    doc->endPage();
  }
  doc->close();

  *handle = mojo::SharedBufferHandle::Create(wstream.bytesWritten());
  DCHECK((*handle).is_valid());

  mojo::ScopedSharedBufferMapping mapping =
      (*handle)->Map(wstream.bytesWritten());
  DCHECK(mapping);
  wstream.copyToAndReset(mapping.get());

  return mojom::PdfCompositor::Status::SUCCESS;
}

sk_sp<SkPicture> PdfCompositorImpl::CompositeSubframe(uint64_t frame_guid) {
  // The content of this frame should be available.
  auto iter = frame_info_map_.find(frame_guid);
  DCHECK(iter != frame_info_map_.end());
  std::unique_ptr<FrameInfo>& frame_info = iter->second;
  frame_info->composited = true;

  // Composite subframes first.
  DeserializationContext subframes =
      GetDeserializationContext(frame_info->subframe_content_map);

  // Composite the entire frame.
  SkMemoryStream stream(iter->second->serialized_content->memory(),
                        iter->second->serialized_content->mapped_size());
  // TODO(weili): Change the default functions to actual implementation.
  SkDeserialProcs procs;
  iter->second->content = SkPicture::MakeFromStream(&stream, &procs);
  return iter->second->content;
}

PdfCompositorImpl::DeserializationContext
PdfCompositorImpl::GetDeserializationContext(
    const ContentToFrameMap& subframe_content_map) {
  DeserializationContext subframes;
  for (auto& content_info : subframe_content_map) {
    uint32_t content_id = content_info.first;
    uint64_t frame_guid = content_info.second;
    auto frame_iter = frame_info_map_.find(frame_guid);
    if (frame_iter == frame_info_map_.end())
      continue;

    if (frame_iter->second->composited)
      subframes[content_id] = frame_iter->second->content;
    else
      subframes[content_id] = CompositeSubframe(frame_iter->first);
  }
  return subframes;
}

void PdfCompositorImpl::FulfillRequest(
    uint64_t frame_guid,
    base::Optional<uint32_t> page_num,
    std::unique_ptr<base::SharedMemory> serialized_content,
    const ContentToFrameMap& subframe_content_map,
    CompositeToPdfCallback callback) {
  mojo::ScopedSharedBufferHandle handle;
  auto status =
      CompositeToPdf(frame_guid, page_num, std::move(serialized_content),
                     subframe_content_map, &handle);
  std::move(callback).Run(status, std::move(handle));
}

PdfCompositorImpl::FrameContentInfo::FrameContentInfo(
    std::unique_ptr<base::SharedMemory> content,
    const ContentToFrameMap& map)
    : serialized_content(std::move(content)), subframe_content_map(map) {}

PdfCompositorImpl::FrameContentInfo::FrameContentInfo() {}

PdfCompositorImpl::FrameContentInfo::~FrameContentInfo() {}

PdfCompositorImpl::FrameInfo::FrameInfo() {}

PdfCompositorImpl::FrameInfo::~FrameInfo() {}

PdfCompositorImpl::RequestInfo::RequestInfo(
    uint64_t frame_guid,
    base::Optional<uint32_t> page_num,
    std::unique_ptr<base::SharedMemory> content,
    const ContentToFrameMap& content_info,
    const base::flat_set<uint64_t>& pending_subframes,
    mojom::PdfCompositor::CompositePageToPdfCallback callback)
    : FrameContentInfo(std::move(content), content_info),
      frame_guid(frame_guid),
      page_number(page_num),
      pending_subframes(pending_subframes),
      callback(std::move(callback)) {}

PdfCompositorImpl::RequestInfo::~RequestInfo() {}

}  // namespace printing
