// Copyright (c) 2011 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 "printing/printed_document.h"

#include <algorithm>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/i18n/file_util_icu.h"
#include "base/i18n/time_formatting.h"
#include "base/json/json_writer.h"
#include "base/lazy_instance.h"
#include "base/memory/ref_counted_memory.h"
#include "base/message_loop/message_loop.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "base/values.h"
#include "printing/metafile.h"
#include "printing/page_number.h"
#include "printing/print_settings_conversion.h"
#include "printing/units.h"
#include "ui/gfx/font.h"
#include "ui/gfx/text_elider.h"

#if defined(OS_WIN)
#include "printing/printed_page_win.h"
#endif

namespace printing {

namespace {

base::LazyInstance<base::FilePath>::Leaky g_debug_dump_info =
    LAZY_INSTANCE_INITIALIZER;

#if defined(OS_WIN)
void DebugDumpPageTask(const base::string16& doc_name,
                       const PrintedPage* page) {
  base::AssertBlockingAllowed();

  DCHECK(PrintedDocument::HasDebugDumpPath());

  static constexpr base::FilePath::CharType kExtension[] =
      FILE_PATH_LITERAL(".emf");

  base::string16 name = doc_name;
  name += base::ASCIIToUTF16(base::StringPrintf("_%04d", page->page_number()));
  base::FilePath path = PrintedDocument::CreateDebugDumpPath(name, kExtension);
  base::File file(path,
                  base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
  page->metafile()->SaveTo(&file);
}
#else
void DebugDumpTask(const base::string16& doc_name,
                   const MetafilePlayer* metafile) {
  base::AssertBlockingAllowed();

  DCHECK(PrintedDocument::HasDebugDumpPath());

  static constexpr base::FilePath::CharType kExtension[] =
      FILE_PATH_LITERAL(".pdf");

  base::string16 name = doc_name;
  base::FilePath path = PrintedDocument::CreateDebugDumpPath(name, kExtension);
  base::File file(path,
                  base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
  metafile->SaveTo(&file);
}
#endif

void DebugDumpDataTask(const base::string16& doc_name,
                       const base::FilePath::StringType& extension,
                       const base::RefCountedMemory* data) {
  base::AssertBlockingAllowed();

  base::FilePath path =
      PrintedDocument::CreateDebugDumpPath(doc_name, extension);
  if (path.empty())
    return;
  base::WriteFile(path,
                  reinterpret_cast<const char*>(data->front()),
                  base::checked_cast<int>(data->size()));
}

void DebugDumpSettings(const base::string16& doc_name,
                       const PrintSettings& settings) {
  base::DictionaryValue job_settings;
  PrintSettingsToJobSettingsDebug(settings, &job_settings);
  std::string settings_str;
  base::JSONWriter::WriteWithOptions(
      job_settings, base::JSONWriter::OPTIONS_PRETTY_PRINT, &settings_str);
  scoped_refptr<base::RefCountedMemory> data =
      base::RefCountedString::TakeString(&settings_str);
  base::PostTaskWithTraits(
      FROM_HERE, {base::TaskPriority::BACKGROUND, base::MayBlock()},
      base::BindOnce(&DebugDumpDataTask, doc_name, FILE_PATH_LITERAL(".json"),
                     base::RetainedRef(data)));
}

}  // namespace

PrintedDocument::PrintedDocument(const PrintSettings& settings,
                                 const base::string16& name,
                                 int cookie)
    : immutable_(settings, name, cookie) {
  // Records the expected page count if a range is setup.
  if (!settings.ranges().empty()) {
    // If there is a range, set the number of page
    for (unsigned i = 0; i < settings.ranges().size(); ++i) {
      const PageRange& range = settings.ranges()[i];
      mutable_.expected_page_count_ += range.to - range.from + 1;
    }
  }

  if (HasDebugDumpPath())
    DebugDumpSettings(name, settings);
}

PrintedDocument::~PrintedDocument() = default;

#if defined(OS_WIN)
void PrintedDocument::SetPage(int page_number,
                              std::unique_ptr<MetafilePlayer> metafile,
                              float shrink,
                              const gfx::Size& page_size,
                              const gfx::Rect& page_content_rect) {
  // Notice the page_number + 1, the reason is that this is the value that will
  // be shown. Users dislike 0-based counting.
  auto page = base::MakeRefCounted<PrintedPage>(
      page_number + 1, std::move(metafile), page_size, page_content_rect);
  page->set_shrink_factor(shrink);
  {
    base::AutoLock lock(lock_);
    mutable_.pages_[page_number] = page;
  }

  if (HasDebugDumpPath()) {
    base::PostTaskWithTraits(
        FROM_HERE, {base::TaskPriority::BACKGROUND, base::MayBlock()},
        base::BindOnce(&DebugDumpPageTask, name(), base::RetainedRef(page)));
  }
}

scoped_refptr<PrintedPage> PrintedDocument::GetPage(int page_number) {
  scoped_refptr<PrintedPage> page;
  {
    base::AutoLock lock(lock_);
    PrintedPages::const_iterator it = mutable_.pages_.find(page_number);
    if (it != mutable_.pages_.end())
      page = it->second;
  }
  return page;
}

#else
void PrintedDocument::SetDocument(std::unique_ptr<MetafilePlayer> metafile,
                                  const gfx::Size& page_size,
                                  const gfx::Rect& page_content_rect) {
  {
    base::AutoLock lock(lock_);
    mutable_.metafile_ = std::move(metafile);
#if defined(OS_MACOSX)
    mutable_.page_size_ = page_size;
    mutable_.page_content_rect_ = page_content_rect;
#endif
  }

  if (HasDebugDumpPath()) {
    base::PostTaskWithTraits(
        FROM_HERE, {base::TaskPriority::BACKGROUND, base::MayBlock()},
        base::BindOnce(&DebugDumpTask, name(), mutable_.metafile_.get()));
  }
}

const MetafilePlayer* PrintedDocument::GetMetafile() {
  return mutable_.metafile_.get();
}

#endif

bool PrintedDocument::IsComplete() const {
  base::AutoLock lock(lock_);
  if (!mutable_.page_count_)
    return false;
#if defined(OS_WIN)
  PageNumber page(immutable_.settings_, mutable_.page_count_);
  if (page == PageNumber::npos())
    return false;

  for (; page != PageNumber::npos(); ++page) {
    PrintedPages::const_iterator it = mutable_.pages_.find(page.ToInt());
    if (it == mutable_.pages_.end() || !it->second.get() ||
        !it->second->metafile()) {
      return false;
    }
  }
  return true;
#else
  return !!mutable_.metafile_;
#endif
}

void PrintedDocument::set_page_count(int max_page) {
  base::AutoLock lock(lock_);
  DCHECK_EQ(0, mutable_.page_count_);
  mutable_.page_count_ = max_page;
  if (immutable_.settings_.ranges().empty()) {
    mutable_.expected_page_count_ = max_page;
  } else {
    // If there is a range, don't bother since expected_page_count_ is already
    // initialized.
    DCHECK_NE(mutable_.expected_page_count_, 0);
  }
}

int PrintedDocument::page_count() const {
  base::AutoLock lock(lock_);
  return mutable_.page_count_;
}

int PrintedDocument::expected_page_count() const {
  base::AutoLock lock(lock_);
  return mutable_.expected_page_count_;
}

// static
void PrintedDocument::SetDebugDumpPath(const base::FilePath& debug_dump_path) {
  DCHECK(!debug_dump_path.empty());
  g_debug_dump_info.Get() = debug_dump_path;
}

// static
bool PrintedDocument::HasDebugDumpPath() {
  return g_debug_dump_info.IsCreated();
}

// static
base::FilePath PrintedDocument::CreateDebugDumpPath(
    const base::string16& document_name,
    const base::FilePath::StringType& extension) {
  DCHECK(HasDebugDumpPath());

  // Create a filename.
  base::string16 filename;
  base::Time now(base::Time::Now());
  filename = base::TimeFormatShortDateAndTime(now);
  filename += base::ASCIIToUTF16("_");
  filename += document_name;
  base::FilePath::StringType system_filename;
#if defined(OS_WIN)
  system_filename = filename;
#else   // OS_WIN
  system_filename = base::UTF16ToUTF8(filename);
#endif  // OS_WIN
  base::i18n::ReplaceIllegalCharactersInPath(&system_filename, '_');
  const auto& dump_path = g_debug_dump_info.Get();
  DCHECK(!dump_path.empty());
  return dump_path.Append(system_filename).AddExtension(extension);
}

void PrintedDocument::DebugDumpData(
    const base::RefCountedMemory* data,
    const base::FilePath::StringType& extension) {
  DCHECK(HasDebugDumpPath());
  base::PostTaskWithTraits(FROM_HERE,
                           {base::TaskPriority::BACKGROUND, base::MayBlock()},
                           base::BindOnce(&DebugDumpDataTask, name(), extension,
                                          base::RetainedRef(data)));
}

#if defined(OS_WIN) || defined(OS_MACOSX)
gfx::Rect PrintedDocument::GetCenteredPageContentRect(
    const gfx::Size& paper_size,
    const gfx::Size& page_size,
    const gfx::Rect& page_content_rect) const {
  gfx::Rect content_rect = page_content_rect;
  if (paper_size.width() > page_size.width()) {
    int diff = paper_size.width() - page_size.width();
    content_rect.set_x(content_rect.x() + diff / 2);
  }
  if (paper_size.height() > page_size.height()) {
    int diff = paper_size.height() - page_size.height();
    content_rect.set_y(content_rect.y() + diff / 2);
  }
  return content_rect;
}
#endif

PrintedDocument::Mutable::Mutable() = default;

PrintedDocument::Mutable::~Mutable() = default;

PrintedDocument::Immutable::Immutable(const PrintSettings& settings,
                                      const base::string16& name,
                                      int cookie)
    : settings_(settings), name_(name), cookie_(cookie) {}

PrintedDocument::Immutable::~Immutable() = default;

#if defined(OS_ANDROID)
// This function is not used on android.
bool PrintedDocument::RenderPrintedDocument(PrintingContext* context) {
  NOTREACHED();
  return false;
}
#endif

}  // namespace printing
