// Copyright (c) 2012 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 "content/browser/renderer_host/clipboard_host_impl.h"

#include <utility>

#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/pickle.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "build/build_config.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/clipboard_constants.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "url/gurl.h"

namespace content {

ClipboardHostImpl::ClipboardHostImpl(blink::mojom::ClipboardHostRequest request)
    : binding_(this, std::move(request)),
      clipboard_(ui::Clipboard::GetForCurrentThread()),
      clipboard_writer_(
          new ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE)) {}

void ClipboardHostImpl::Create(blink::mojom::ClipboardHostRequest request) {
  // Clipboard implementations do interesting things, like run nested message
  // loops. Since StrongBinding<T> synchronously destroys on failure, that can
  // result in some unfortunate use-after-frees after the nested message loops
  // exit.
  auto* host = new ClipboardHostImpl(std::move(request));
  host->binding_.set_connection_error_handler(base::BindOnce(
      [](ClipboardHostImpl* host) {
        base::SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, host);
      },
      host));
}

ClipboardHostImpl::~ClipboardHostImpl() {
  clipboard_writer_->Reset();
}

void ClipboardHostImpl::GetSequenceNumber(ui::ClipboardType clipboard_type,
                                          GetSequenceNumberCallback callback) {
  std::move(callback).Run(clipboard_->GetSequenceNumber(clipboard_type));
}

void ClipboardHostImpl::ReadAvailableTypes(
    ui::ClipboardType clipboard_type,
    ReadAvailableTypesCallback callback) {
  std::vector<base::string16> types;
  bool contains_filenames;
  clipboard_->ReadAvailableTypes(clipboard_type, &types, &contains_filenames);
  std::move(callback).Run(types, contains_filenames);
}

void ClipboardHostImpl::IsFormatAvailable(blink::mojom::ClipboardFormat format,
                                          ui::ClipboardType clipboard_type,
                                          IsFormatAvailableCallback callback) {
  bool result = false;
  switch (format) {
    case blink::mojom::ClipboardFormat::kPlaintext:
      result =
          clipboard_->IsFormatAvailable(
              ui::ClipboardFormatType::GetPlainTextWType(), clipboard_type) ||
          clipboard_->IsFormatAvailable(
              ui::ClipboardFormatType::GetPlainTextType(), clipboard_type);
      break;
    case blink::mojom::ClipboardFormat::kHtml:
      result = clipboard_->IsFormatAvailable(
          ui::ClipboardFormatType::GetHtmlType(), clipboard_type);
      break;
    case blink::mojom::ClipboardFormat::kSmartPaste:
      result = clipboard_->IsFormatAvailable(
          ui::ClipboardFormatType::GetWebKitSmartPasteType(), clipboard_type);
      break;
    case blink::mojom::ClipboardFormat::kBookmark:
#if defined(OS_WIN) || defined(OS_MACOSX)
      result = clipboard_->IsFormatAvailable(
          ui::ClipboardFormatType::GetUrlWType(), clipboard_type);
#else
      result = false;
#endif
      break;
  }
  std::move(callback).Run(result);
}

void ClipboardHostImpl::ReadText(ui::ClipboardType clipboard_type,
                                 ReadTextCallback callback) {
  base::string16 result;
  if (clipboard_->IsFormatAvailable(
          ui::ClipboardFormatType::GetPlainTextWType(), clipboard_type)) {
    clipboard_->ReadText(clipboard_type, &result);
  } else if (clipboard_->IsFormatAvailable(
                 ui::ClipboardFormatType::GetPlainTextType(), clipboard_type)) {
    std::string ascii;
    clipboard_->ReadAsciiText(clipboard_type, &ascii);
    result = base::ASCIIToUTF16(ascii);
  }
  std::move(callback).Run(result);
}

void ClipboardHostImpl::ReadHtml(ui::ClipboardType clipboard_type,
                                 ReadHtmlCallback callback) {
  base::string16 markup;
  std::string src_url_str;
  uint32_t fragment_start = 0;
  uint32_t fragment_end = 0;
  clipboard_->ReadHTML(clipboard_type, &markup, &src_url_str, &fragment_start,
                       &fragment_end);
  std::move(callback).Run(std::move(markup), GURL(src_url_str), fragment_start,
                          fragment_end);
}

void ClipboardHostImpl::ReadRtf(ui::ClipboardType clipboard_type,
                                ReadRtfCallback callback) {
  std::string result;
  clipboard_->ReadRTF(clipboard_type, &result);
  std::move(callback).Run(result);
}

void ClipboardHostImpl::ReadImage(ui::ClipboardType clipboard_type,
                                  ReadImageCallback callback) {
  SkBitmap result = clipboard_->ReadImage(clipboard_type);
  std::move(callback).Run(result);
}

void ClipboardHostImpl::ReadCustomData(ui::ClipboardType clipboard_type,
                                       const base::string16& type,
                                       ReadCustomDataCallback callback) {
  base::string16 result;
  clipboard_->ReadCustomData(clipboard_type, type, &result);
  std::move(callback).Run(result);
}

void ClipboardHostImpl::WriteText(ui::ClipboardType,
                                  const base::string16& text) {
  clipboard_writer_->WriteText(text);
}

void ClipboardHostImpl::WriteHtml(ui::ClipboardType,
                                  const base::string16& markup,
                                  const GURL& url) {
  clipboard_writer_->WriteHTML(markup, url.spec());
}

void ClipboardHostImpl::WriteSmartPasteMarker(ui::ClipboardType) {
  clipboard_writer_->WriteWebSmartPaste();
}

void ClipboardHostImpl::WriteCustomData(
    ui::ClipboardType,
    const base::flat_map<base::string16, base::string16>& data) {
  base::Pickle pickle;
  ui::WriteCustomDataToPickle(data, &pickle);
  clipboard_writer_->WritePickledData(
      pickle, ui::ClipboardFormatType::GetWebCustomDataType());
}

void ClipboardHostImpl::WriteBookmark(ui::ClipboardType,
                                      const std::string& url,
                                      const base::string16& title) {
  clipboard_writer_->WriteBookmark(title, url);
}

void ClipboardHostImpl::WriteImage(ui::ClipboardType, const SkBitmap& bitmap) {
  clipboard_writer_->WriteImage(bitmap);
}

void ClipboardHostImpl::CommitWrite(ui::ClipboardType) {
  clipboard_writer_.reset(
      new ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE));
}

}  // namespace content
