// Copyright 2015 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 "android_webview/browser/aw_print_manager.h"

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted_memory.h"
#include "base/numerics/safe_conversions.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "components/printing/browser/print_manager_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"

namespace android_webview {

namespace {

int SaveDataToFd(int fd,
                 int page_count,
                 scoped_refptr<base::RefCountedSharedMemoryMapping> data) {
  base::File file(fd);
  bool result =
      file.IsValid() && base::IsValueInRangeForNumericType<int>(data->size());
  if (result) {
    int size = data->size();
    result = file.WriteAtCurrentPos(data->front_as<char>(), size) == size;
  }
  file.TakePlatformFile();
  return result ? page_count : 0;
}

}  // namespace

struct AwPrintManager::FrameDispatchHelper {
  AwPrintManager* manager;
  content::RenderFrameHost* render_frame_host;

  bool Send(IPC::Message* msg) { return render_frame_host->Send(msg); }

  void OnGetDefaultPrintSettings(IPC::Message* reply_msg) {
    manager->OnGetDefaultPrintSettings(render_frame_host, reply_msg);
  }

  void OnScriptedPrint(const PrintHostMsg_ScriptedPrint_Params& scripted_params,
                       IPC::Message* reply_msg) {
    manager->OnScriptedPrint(render_frame_host, scripted_params, reply_msg);
  }
};

// static
AwPrintManager* AwPrintManager::CreateForWebContents(
    content::WebContents* contents,
    const printing::PrintSettings& settings,
    int file_descriptor,
    PrintManager::PdfWritingDoneCallback callback) {
  AwPrintManager* print_manager = new AwPrintManager(
      contents, settings, file_descriptor, std::move(callback));
  contents->SetUserData(UserDataKey(), base::WrapUnique(print_manager));
  return print_manager;
}

AwPrintManager::AwPrintManager(content::WebContents* contents,
                               const printing::PrintSettings& settings,
                               int file_descriptor,
                               PdfWritingDoneCallback callback)
    : PrintManager(contents), settings_(settings), fd_(file_descriptor) {
  pdf_writing_done_callback_ = std::move(callback);
  cookie_ = 1;  // Set a valid dummy cookie value.
}

AwPrintManager::~AwPrintManager() = default;

void AwPrintManager::PdfWritingDone(int page_count) {
  if (pdf_writing_done_callback_)
    pdf_writing_done_callback_.Run(page_count);
  // Invalidate the file descriptor so it doesn't get reused.
  fd_ = -1;
}

bool AwPrintManager::PrintNow() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  auto* rfh = web_contents()->GetMainFrame();
  return rfh->Send(new PrintMsg_PrintPages(rfh->GetRoutingID()));
}

bool AwPrintManager::OnMessageReceived(
    const IPC::Message& message,
    content::RenderFrameHost* render_frame_host) {
  FrameDispatchHelper helper = {this, render_frame_host};
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(AwPrintManager, message, render_frame_host)
    IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintDocument, OnDidPrintDocument)
    IPC_MESSAGE_FORWARD_DELAY_REPLY(
        PrintHostMsg_GetDefaultPrintSettings, &helper,
        FrameDispatchHelper::OnGetDefaultPrintSettings)
    IPC_MESSAGE_FORWARD_DELAY_REPLY(PrintHostMsg_ScriptedPrint, &helper,
                                    FrameDispatchHelper::OnScriptedPrint)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled || PrintManager::OnMessageReceived(message, render_frame_host);
}

void AwPrintManager::OnGetDefaultPrintSettings(
    content::RenderFrameHost* render_frame_host,
    IPC::Message* reply_msg) {
  // Unlike the printing_message_filter, we do process this in UI thread.
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  PrintMsg_Print_Params params;
  printing::RenderParamsFromPrintSettings(settings_, &params);
  params.document_cookie = cookie_;
  PrintHostMsg_GetDefaultPrintSettings::WriteReplyParams(reply_msg, params);
  render_frame_host->Send(reply_msg);
}

void AwPrintManager::OnScriptedPrint(
    content::RenderFrameHost* render_frame_host,
    const PrintHostMsg_ScriptedPrint_Params& scripted_params,
    IPC::Message* reply_msg) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  PrintMsg_PrintPages_Params params;
  printing::RenderParamsFromPrintSettings(settings_, &params.params);
  params.params.document_cookie = scripted_params.cookie;
  params.pages = printing::PageRange::GetPages(settings_.ranges());
  PrintHostMsg_ScriptedPrint::WriteReplyParams(reply_msg, params);
  render_frame_host->Send(reply_msg);
}

void AwPrintManager::OnDidPrintDocument(
    content::RenderFrameHost* render_frame_host,
    const PrintHostMsg_DidPrintDocument_Params& params) {
  if (params.document_cookie != cookie_)
    return;

  const PrintHostMsg_DidPrintContent_Params& content = params.content;
  if (!content.metafile_data_region.IsValid()) {
    NOTREACHED() << "invalid memory handle";
    web_contents()->Stop();
    PdfWritingDone(0);
    return;
  }

  auto data = base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(
      content.metafile_data_region);
  if (!data) {
    NOTREACHED() << "couldn't map";
    web_contents()->Stop();
    PdfWritingDone(0);
    return;
  }

  base::PostTaskAndReplyWithResult(
      base::CreateTaskRunnerWithTraits(
          {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
           base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})
          .get(),
      FROM_HERE, base::BindRepeating(&SaveDataToFd, fd_, number_pages_, data),
      pdf_writing_done_callback_);
}

WEB_CONTENTS_USER_DATA_KEY_IMPL(AwPrintManager)

}  // namespace android_webview
