// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/printing/print_job.h"

#include <memory>
#include <utility>

#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/metrics/histogram_functions.h"
#include "base/observer_list.h"
#include "base/run_loop.h"
#include "base/task/thread_pool.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/print_job_worker.h"
#include "chrome/browser/printing/printer_query.h"
#include "components/enterprise/buildflags/buildflags.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "printing/mojom/print.mojom.h"
#include "printing/printed_document.h"

#if BUILDFLAG(IS_WIN)
#include <optional>

#include "base/command_line.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/pdf/pdf_pref_names.h"
#include "chrome/browser/printing/pdf_to_emf_converter.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "printing/backend/win_helper.h"
#include "printing/page_number.h"
#include "printing/pdf_render_settings.h"
#include "printing/printed_page_win.h"
#include "printing/printing_features.h"
#include "url/gurl.h"
#endif


namespace printing {

namespace {

// Helper function to ensure `job` is valid until at least `callback` returns.
void HoldRefCallback(scoped_refptr<PrintJob> job, base::OnceClosure callback) {
  std::move(callback).Run();
}

#if BUILDFLAG(IS_WIN)
// Those must be kept in sync with the values defined in policy_templates.json.
enum class PrintPostScriptMode {
  // Do normal PostScript generation. Text is always rendered with Type 3 fonts.
  // Default value when policy not set.
  kDefault = 0,
  // Text is rendered with Type 42 fonts if possible.
  kType42 = 1,
  kMaxValue = kType42,
};

// Those must be kept in sync with the values defined in policy_templates.json.
enum class PrintRasterizationMode {
  // Do full page rasterization if necessary. Default value when policy not set.
  kFull = 0,
  // Avoid rasterization if possible.
  kFast = 1,
  kMaxValue = kFast,
};

bool PrintWithPostScriptType42Fonts(PrefService* prefs) {
  // Managed preference takes precedence over user preference and field trials.
  if (prefs && prefs->IsManagedPreference(prefs::kPrintPostScriptMode)) {
    int value = prefs->GetInteger(prefs::kPrintPostScriptMode);
    return value == static_cast<int>(PrintPostScriptMode::kType42);
  }

  return base::FeatureList::IsEnabled(
      features::kPrintWithPostScriptType42Fonts);
}

bool PrintWithReducedRasterization(PrefService* prefs) {
  // Managed preference takes precedence over user preference and field trials.
  if (prefs && prefs->IsManagedPreference(prefs::kPrintRasterizationMode)) {
    int value = prefs->GetInteger(prefs::kPrintRasterizationMode);
    return value == static_cast<int>(PrintRasterizationMode::kFast);
  }

  return base::FeatureList::IsEnabled(features::kPrintWithReducedRasterization);
}

PrefService* GetPrefsForWebContents(content::WebContents* web_contents) {
  // TODO(thestig): Figure out why crbug.com/1083911 occurred, which is likely
  // because `web_contents` was null. As a result, this section has many more
  // pointer checks to avoid crashing.
  content::BrowserContext* context =
      web_contents ? web_contents->GetBrowserContext() : nullptr;
  return context ? Profile::FromBrowserContext(context)->GetPrefs() : nullptr;
}

content::WebContents* GetWebContents(content::GlobalRenderFrameHostId rfh_id) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  auto* rfh = content::RenderFrameHost::FromID(rfh_id);
  return rfh ? content::WebContents::FromRenderFrameHost(rfh) : nullptr;
}

#endif  // BUILDFLAG(IS_WIN)

}  // namespace

PrintJob::PrintJob(PrintJobManager* print_job_manager)
    : print_job_manager_(print_job_manager) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(print_job_manager_);
}

PrintJob::PrintJob() = default;

PrintJob::~PrintJob() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  // The job should be finished (or at least canceled) when it is destroyed.
  DCHECK(!is_job_pending_);
  DCHECK(!is_canceling_);
  DCHECK(!worker_ || !worker_->IsRunning());

  for (auto& observer : observers_) {
    observer.OnDestruction();
  }
}

void PrintJob::Initialize(std::unique_ptr<PrinterQuery> query,
                          const std::u16string& name,
                          uint32_t page_count) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(!worker_);
  DCHECK(!is_job_pending_);
  DCHECK(!is_canceling_);
  DCHECK(!document_);
  worker_ = query->TransferContextToNewWorker(this);
  worker_->Start();
  rfh_id_ = query->rfh_id();
  std::unique_ptr<PrintSettings> settings = query->ExtractSettings();

#if BUILDFLAG(IS_WIN)
  pdf_page_mapping_ = PageNumber::GetPages(settings->ranges(), page_count);
  PrefService* prefs = GetPrefsForWebContents(GetWebContents(rfh_id_));
  if (prefs && prefs->IsManagedPreference(prefs::kPdfUseSkiaRendererEnabled)) {
    use_skia_ = prefs->GetBoolean(prefs::kPdfUseSkiaRendererEnabled);
  }
#endif

  auto new_doc = base::MakeRefCounted<PrintedDocument>(std::move(settings),
                                                       name, query->cookie());
  new_doc->set_page_count(page_count);
  UpdatePrintedDocument(new_doc);
}

#if BUILDFLAG(IS_WIN)
// static
std::vector<uint32_t> PrintJob::GetFullPageMapping(
    const std::vector<uint32_t>& pages,
    uint32_t total_page_count) {
  std::vector<uint32_t> mapping(total_page_count, kInvalidPageIndex);
  for (uint32_t page_index : pages) {
    // Make sure the page is in range.
    if (page_index < total_page_count) {
      mapping[page_index] = page_index;
    }
  }
  return mapping;
}

void PrintJob::StartConversionToNativeFormat(
    scoped_refptr<base::RefCountedMemory> print_data,
    const gfx::Size& page_size,
    const gfx::Rect& content_area,
    const gfx::Point& physical_offsets,
    const GURL& url) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (PrintedDocument::HasDebugDumpPath())
    document()->DebugDumpData(print_data.get(), FILE_PATH_LITERAL(".pdf"));

  const PrintSettings& settings = document()->settings();
  if (settings.printer_language_is_textonly()) {
    StartPdfToTextConversion(print_data, page_size, url);
  } else if (settings.printer_language_is_ps2() ||
             settings.printer_language_is_ps3()) {
    StartPdfToPostScriptConversion(print_data, content_area, physical_offsets,
                                   settings.printer_language_is_ps2(), url);
  } else {
    StartPdfToEmfConversion(print_data, page_size, content_area, url);
  }

  // Indicate that the PDF is fully rendered and we no longer need the renderer
  // and web contents, so the print job does not need to be cancelled if they
  // die. This is needed on Windows because the `PrintedDocument` will not be
  // considered complete until PDF conversion finishes.
  document()->SetConvertingPdf();
}

void PrintJob::ResetPageMapping() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  pdf_page_mapping_ =
      GetFullPageMapping(pdf_page_mapping_, document_->page_count());
}
#endif  // BUILDFLAG(IS_WIN)

void PrintJob::StartPrinting() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (!worker_->IsRunning() || is_job_pending_) {
    NOTREACHED();
  }

#if BUILDFLAG(IS_WIN)
  // Do not collect duration metric if the print job will need to invoke a
  // "Save Print Output As" dialog that waits on a user to select a filename.
  const std::string printer_name =
      base::UTF16ToUTF8(document_->settings().device_name());
  const bool capture_printing_time =
      !DoesDriverDisplayFileDialogForPrinting(printer_name);
#else
  constexpr bool capture_printing_time = true;
#endif
  if (capture_printing_time) {
    printing_start_time_ = base::TimeTicks::Now();
  }

  // Real work is done in `PrintJobWorker::StartPrinting()`.
  worker_->PostTask(
      FROM_HERE, base::BindOnce(&HoldRefCallback, base::WrapRefCounted(this),
                                base::BindOnce(&PrintJobWorker::StartPrinting,
                                               base::Unretained(worker_.get()),
                                               base::RetainedRef(document_))));
  // Set the flag right now.
  is_job_pending_ = true;

  print_job_manager_->OnStarted(this);
}

void PrintJob::Stop() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (quit_closure_) {
    // In case we're running a nested run loop to wait for a job to finish,
    // and we finished before the timeout, quit the nested loop right away.
    std::move(quit_closure_).Run();
  }

  // Be sure to live long enough.
  scoped_refptr<PrintJob> handle(this);

  if (worker_->IsRunning()) {
    ControlledWorkerShutdown();
  } else {
    // Flush the cached document.
    is_job_pending_ = false;
    ClearPrintedDocument();
  }
}

void PrintJob::Cancel() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (is_canceling_)
    return;

  is_canceling_ = true;

  for (auto& observer : observers_) {
    observer.OnCanceling();
  }

  if (worker_ && worker_->IsRunning()) {
    // Call this right now so it renders the context invalid. Do not use
    // InvokeLater since it would take too much time.
    worker_->Cancel();
  }
  OnFailed();
  is_canceling_ = false;
}

#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
void PrintJob::CleanupAfterContentAnalysisDenial() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  worker_->CleanupAfterContentAnalysisDenial();
}
#endif

bool PrintJob::FlushJob(base::TimeDelta timeout) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  // Make sure the object outlive this message loop.
  scoped_refptr<PrintJob> handle(this);

  base::RunLoop loop(base::RunLoop::Type::kNestableTasksAllowed);
  quit_closure_ = loop.QuitClosure();
  content::GetUIThreadTaskRunner({})->PostDelayedTask(
      FROM_HERE, loop.QuitClosure(), timeout);

  loop.Run();

  return true;
}

bool PrintJob::is_job_pending() const {
  return is_job_pending_;
}

PrintedDocument* PrintJob::document() const {
  return document_.get();
}

const PrintSettings& PrintJob::settings() const {
  return document()->settings();
}

#if BUILDFLAG(IS_CHROMEOS)
void PrintJob::SetSource(PrintJob::Source source,
                         const std::string& source_id) {
  source_ = source;
  source_id_ = source_id;
}

PrintJob::Source PrintJob::source() const {
  return source_;
}

const std::string& PrintJob::source_id() const {
  return source_id_;
}
#endif  // BUILDFLAG(IS_CHROMEOS)

#if BUILDFLAG(IS_WIN)
class PrintJob::PdfConversionState {
 public:
  PdfConversionState(const gfx::Size& page_size,
                     const gfx::Rect& content_area,
                     const std::optional<bool>& use_skia,
                     const GURL& url)
      : page_size_(page_size),
        content_area_(content_area),
        use_skia_(use_skia),
        url_(url) {}

  void Start(scoped_refptr<base::RefCountedMemory> data,
             const PdfRenderSettings& conversion_settings,
             PdfConverter::StartCallback start_callback) {
    converter_ = PdfConverter::StartPdfConverter(
        data, conversion_settings, use_skia_, url_, std::move(start_callback));
  }

  void GetMorePages(PdfConverter::GetPageCallback get_page_callback) {
    const int kMaxNumberOfTempFilesPerDocument = 3;
    while (pages_in_progress_ < kMaxNumberOfTempFilesPerDocument &&
           current_page_index_ < page_count_) {
      ++pages_in_progress_;
      converter_->GetPage(current_page_index_++, get_page_callback);
    }
  }

  void OnPageProcessed(PdfConverter::GetPageCallback get_page_callback) {
    --pages_in_progress_;
    GetMorePages(get_page_callback);
    // Release converter if we don't need this any more.
    if (!pages_in_progress_ && current_page_index_ >= page_count_)
      converter_.reset();
  }

  void set_page_count(uint32_t page_count) { page_count_ = page_count; }
  const gfx::Size& page_size() const { return page_size_; }
  const gfx::Rect& content_area() const { return content_area_; }

 private:
  uint32_t page_count_ = 0;
  uint32_t current_page_index_ = 0;
  int pages_in_progress_ = 0;
  const gfx::Size page_size_;
  const gfx::Rect content_area_;
  const std::optional<bool> use_skia_;
  const GURL url_;
  std::unique_ptr<PdfConverter> converter_;
};

void PrintJob::StartPdfToEmfConversion(
    scoped_refptr<base::RefCountedMemory> bytes,
    const gfx::Size& page_size,
    const gfx::Rect& content_area,
    const GURL& url) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(!pdf_conversion_state_);
  pdf_conversion_state_ = std::make_unique<PdfConversionState>(
      page_size, content_area, use_skia_, url);

  const PrintSettings& settings = document()->settings();

  PrefService* prefs = GetPrefsForWebContents(GetWebContents(rfh_id_));
  bool print_with_reduced_rasterization = PrintWithReducedRasterization(prefs);

  using RenderMode = PdfRenderSettings::Mode;
  RenderMode mode = print_with_reduced_rasterization
                        ? RenderMode::EMF_WITH_REDUCED_RASTERIZATION
                        : RenderMode::NORMAL;

  PdfRenderSettings render_settings(
      content_area, gfx::Point(0, 0), settings.dpi_size(),
      /*autorotate=*/true, settings.color() == mojom::ColorModel::kColor, mode);
  pdf_conversion_state_->Start(
      bytes, render_settings,
      base::BindOnce(&PrintJob::OnPdfConversionStarted, this));
}

void PrintJob::OnPdfConversionStarted(uint32_t page_count) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (page_count <= 0) {
    // Be sure to live long enough.
    scoped_refptr<PrintJob> handle(this);
    pdf_conversion_state_.reset();
    Cancel();
    return;
  }
  pdf_conversion_state_->set_page_count(page_count);
  pdf_conversion_state_->GetMorePages(
      base::BindRepeating(&PrintJob::OnPdfPageConverted, this));
}

void PrintJob::OnPdfPageConverted(uint32_t page_index,
                                  float scale_factor,
                                  std::unique_ptr<MetafilePlayer> metafile) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(pdf_conversion_state_);
  if (!document_ || !metafile || page_index == kInvalidPageIndex ||
      page_index >= pdf_page_mapping_.size()) {
    // Be sure to live long enough.
    scoped_refptr<PrintJob> handle(this);
    pdf_conversion_state_.reset();
    Cancel();
    return;
  }

  // Add the page to the document if it is one of the pages requested by the
  // user. If it is not, ignore it.
  if (pdf_page_mapping_[page_index] != kInvalidPageIndex) {
    // Update the rendered document. It will send notifications to the listener.
    document_->SetPage(pdf_page_mapping_[page_index], std::move(metafile),
                       scale_factor, pdf_conversion_state_->page_size(),
                       pdf_conversion_state_->content_area());
  }

  pdf_conversion_state_->GetMorePages(
      base::BindRepeating(&PrintJob::OnPdfPageConverted, this));
}

void PrintJob::StartPdfToTextConversion(
    scoped_refptr<base::RefCountedMemory> bytes,
    const gfx::Size& page_size,
    const GURL& url) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(!pdf_conversion_state_);
  pdf_conversion_state_ = std::make_unique<PdfConversionState>(
      gfx::Size(), gfx::Rect(), use_skia_, url);
  gfx::Rect page_area = gfx::Rect(0, 0, page_size.width(), page_size.height());
  const PrintSettings& settings = document()->settings();
  PdfRenderSettings render_settings(
      page_area, gfx::Point(0, 0), settings.dpi_size(),
      /*autorotate=*/true,
      /*use_color=*/true, PdfRenderSettings::Mode::TEXTONLY);
  pdf_conversion_state_->Start(
      bytes, render_settings,
      base::BindOnce(&PrintJob::OnPdfConversionStarted, this));
}

void PrintJob::StartPdfToPostScriptConversion(
    scoped_refptr<base::RefCountedMemory> bytes,
    const gfx::Rect& content_area,
    const gfx::Point& physical_offsets,
    bool ps_level2,
    const GURL& url) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(!pdf_conversion_state_);
  pdf_conversion_state_ = std::make_unique<PdfConversionState>(
      gfx::Size(), gfx::Rect(), use_skia_, url);
  const PrintSettings& settings = document()->settings();

  PdfRenderSettings::Mode mode;
  if (ps_level2) {
    mode = PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2;
  } else {
    PrefService* prefs = GetPrefsForWebContents(GetWebContents(rfh_id_));
    mode = PrintWithPostScriptType42Fonts(prefs)
               ? PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3_WITH_TYPE42_FONTS
               : PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3;
  }
  PdfRenderSettings render_settings(
      content_area, physical_offsets, settings.dpi_size(),
      /*autorotate=*/true, settings.color() == mojom::ColorModel::kColor, mode);
  pdf_conversion_state_->Start(
      bytes, render_settings,
      base::BindOnce(&PrintJob::OnPdfConversionStarted, this));
}
#endif  // BUILDFLAG(IS_WIN)

void PrintJob::UpdatePrintedDocument(
    scoped_refptr<PrintedDocument> new_document) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(new_document);

  document_ = new_document;
  if (worker_)
    SyncPrintedDocumentToWorker();
}

void PrintJob::ClearPrintedDocument() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (!document_)
    return;

  document_ = nullptr;
  if (worker_)
    SyncPrintedDocumentToWorker();
}

void PrintJob::SyncPrintedDocumentToWorker() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(worker_);
  DCHECK(!is_job_pending_);
  worker_->PostTask(
      FROM_HERE,
      base::BindOnce(&HoldRefCallback, base::WrapRefCounted(this),
                     base::BindOnce(&PrintJobWorker::OnDocumentChanged,
                                    base::Unretained(worker_.get()),
                                    base::RetainedRef(document_))));
}

#if BUILDFLAG(IS_WIN)
void PrintJob::OnPageDone(PrintedPage* page) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  if (pdf_conversion_state_) {
    pdf_conversion_state_->OnPageProcessed(
        base::BindRepeating(&PrintJob::OnPdfPageConverted, this));
  }
  document_->RemovePage(page);
}
#endif  // BUILDFLAG(IS_WIN)

void PrintJob::OnFailed() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  Stop();

  print_job_manager_->OnFailed(this);

  for (auto& observer : observers_) {
    observer.OnFailed();
  }
}

void PrintJob::OnDocDone(int job_id, PrintedDocument* document) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (printing_start_time_.has_value()) {
    base::UmaHistogramMediumTimes(
        "Printing.PrintDuration.LocalPrinter.Success",
        base::TimeTicks::Now() - printing_start_time_.value());
    printing_start_time_.reset();
  }

  print_job_manager_->OnDocDone(this, document, job_id);

  for (auto& observer : observers_) {
    observer.OnDocDone(job_id, document);
  }

  // This will call `Stop()` and broadcast a `JOB_DONE` message.
  content::GetUIThreadTaskRunner({})->PostTask(
      FROM_HERE, base::BindOnce(&PrintJob::OnDocumentDone, this));
}

void PrintJob::OnDocumentDone() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  // Be sure to live long enough. The instance could be destroyed by the
  // `JOB_DONE` broadcast.
  scoped_refptr<PrintJob> handle(this);

  // Stop the worker thread.
  Stop();

  print_job_manager_->OnJobDone(this);

  for (auto& observer : observers_) {
    observer.OnJobDone();
  }
}

void PrintJob::ControlledWorkerShutdown() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  // The deadlock this code works around is specific to window messaging on
  // Windows, so we aren't likely to need it on any other platforms.
#if BUILDFLAG(IS_WIN)
  // We could easily get into a deadlock case if worker_->Stop() is used; the
  // printer driver created a window as a child of the browser window. By
  // canceling the job, the printer driver initiated dialog box is destroyed,
  // which sends a blocking message to its parent window. If the browser window
  // thread is not processing messages, a deadlock occurs.
  //
  // This function ensures that the dialog box will be destroyed in a timely
  // manner by the mere fact that the thread will terminate. So the potential
  // deadlock is eliminated.
  worker_->StopSoon();

  // Delay shutdown until the worker terminates.  We want this code path
  // to wait on the thread to quit before continuing.
  if (worker_->IsRunning()) {
    content::GetUIThreadTaskRunner({})->PostDelayedTask(
        FROM_HERE, base::BindOnce(&PrintJob::ControlledWorkerShutdown, this),
        base::Milliseconds(100));
    return;
  }
#endif

  // Now make sure the thread object is cleaned up. Do this on a worker
  // thread because it may block.
  base::ThreadPool::PostTaskAndReply(
      FROM_HERE,
      {base::MayBlock(), base::WithBaseSyncPrimitives(),
       base::TaskPriority::BEST_EFFORT,
       base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
      base::BindOnce(&PrintJobWorker::Stop, base::Unretained(worker_.get())),
      base::BindOnce(&PrintJob::HoldUntilStopIsCalled, this));

  is_job_pending_ = false;
  ClearPrintedDocument();
}

bool PrintJob::PostTask(const base::Location& from_here,
                        base::OnceClosure task) {
  return content::GetUIThreadTaskRunner({})->PostTask(from_here,
                                                      std::move(task));
}

void PrintJob::HoldUntilStopIsCalled() {
}

void PrintJob::set_job_pending_for_testing(bool pending) {
  is_job_pending_ = pending;
}

void PrintJob::AddObserver(Observer& observer) {
  observers_.AddObserver(&observer);
}

void PrintJob::RemoveObserver(Observer& observer) {
  observers_.RemoveObserver(&observer);
}

}  // namespace printing
