// 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/exo/data_source.h"

#include <limits>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/files/file_util.h"
#include "base/i18n/character_encoding.h"
#include "base/i18n/icu_string_conversions.h"
#include "base/optional.h"
#include "base/posix/eintr_wrapper.h"
#include "base/strings/string_util.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "components/exo/data_source_delegate.h"
#include "components/exo/data_source_observer.h"
#include "components/exo/mime_utils.h"
#include "net/base/mime_util.h"
#include "third_party/blink/public/common/mime_util/mime_util.h"
#include "third_party/icu/source/common/unicode/ucnv.h"
#include "ui/base/clipboard/clipboard_constants.h"

namespace exo {

namespace {

constexpr char kTextPlain[] = "text/plain";
constexpr char kTextRTF[] = "text/rtf";
constexpr char kTextHTML[] = "text/html";
constexpr char kTextUriList[] = "text/uri-list";

constexpr char kUtfPrefix[] = "UTF";
constexpr char kEncoding16[] = "16";
constexpr char kEncodingASCII[] = "ASCII";

constexpr char kUTF16Unspecified[] = "UTF-16";
constexpr char kUTF16LittleEndian[] = "UTF-16LE";
constexpr char kUTF16BigEndian[] = "UTF-16BE";
constexpr uint8_t kByteOrderMark[] = {0xFE, 0xFF};
constexpr int kByteOrderMarkSize = sizeof(kByteOrderMark);

constexpr char kImageBitmap[] = "image/bmp";
constexpr char kImagePNG[] = "image/png";
constexpr char kImageAPNG[] = "image/apng";

base::Optional<std::vector<uint8_t>> ReadDataOnWorkerThread(base::ScopedFD fd) {
  constexpr size_t kChunkSize = 1024;
  std::vector<uint8_t> bytes;
  while (true) {
    uint8_t chunk[kChunkSize];
    ssize_t bytes_read = HANDLE_EINTR(read(fd.get(), chunk, kChunkSize));
    if (bytes_read > 0) {
      bytes.insert(bytes.end(), chunk, chunk + bytes_read);
      continue;
    }
    if (!bytes_read)
      return bytes;
    if (bytes_read < 0) {
      PLOG(ERROR) << "Failed to read selection data from clipboard";
      return base::nullopt;
    }
  }
}

// Map a named character set to an integer ranking, lower is better. This is an
// implementation detail of DataSource::GetPreferredMimeTypes and should not be
// considered to have any greater meaning. In particular, these are not expected
// to remain stable over time.
int GetCharsetRank(const std::string& charset_input) {
  std::string charset = base::ToUpperASCII(charset_input);

  // Prefer UTF-16 over all other encodings, because that's what the clipboard
  // interface takes as input; then other unicode encodings; then any non-ASCII
  // encoding, because most or all such encodings are super-sets of ASCII;
  // finally, only use ASCII if nothing else is available.
  if (base::StartsWith(charset, kUtfPrefix, base::CompareCase::SENSITIVE)) {
    if (charset.find(kEncoding16) != std::string::npos)
      return 0;
    return 1;
  } else if (charset.find(kEncodingASCII) == std::string::npos) {
    return 2;
  }
  return 3;
}

// Map an image MIME type to an integer ranking, lower is better. This is an
// implementation detail of DataSource::GetPreferredMimeTypes and should not be
// considered to have any greater meaning. In particular, these are not expected
// to remain stable over time.
int GetImageTypeRank(const std::string& mime_type) {
  // Prefer bitmaps most of all to avoid needing to decode the image, followed
  // by other lossless formats, followed by any other format we support.
  if (net::MatchesMimeType(std::string(kImageBitmap), mime_type))
    return 0;
  if (net::MatchesMimeType(std::string(kImagePNG), mime_type) ||
      net::MatchesMimeType(std::string(kImageAPNG), mime_type))
    return 1;
  return 2;
}

std::u16string CodepageToUTF16(const std::vector<uint8_t>& data,
                               const std::string& charset_input) {
  std::u16string output;
  base::StringPiece piece(reinterpret_cast<const char*>(data.data()),
                          data.size());
  const char* charset = charset_input.c_str();

  // Despite claims in the documentation to the contrary, the ICU UTF-16
  // converter does not automatically detect and interpret the byte order
  // mark. Therefore, we must do this ourselves.
  if (!ucnv_compareNames(charset, kUTF16Unspecified) &&
      data.size() >= kByteOrderMarkSize) {
    if (static_cast<uint8_t>(piece.data()[0]) == kByteOrderMark[0] &&
        static_cast<uint8_t>(piece.data()[1]) == kByteOrderMark[1]) {
      // BOM is in big endian format. Consume the BOM so it doesn't get
      // interpreted as a character.
      piece.remove_prefix(2);
      charset = kUTF16BigEndian;
    } else if (static_cast<uint8_t>(piece.data()[0]) == kByteOrderMark[1] &&
               static_cast<uint8_t>(piece.data()[1]) == kByteOrderMark[0]) {
      // BOM is in little endian format. Consume the BOM so it doesn't get
      // interpreted as a character.
      piece.remove_prefix(2);
      charset = kUTF16LittleEndian;
    }
  }

  base::CodepageToUTF16(
      piece, charset, base::OnStringConversionError::Type::SUBSTITUTE, &output);
  return output;
}

}  // namespace

ScopedDataSource::ScopedDataSource(DataSource* data_source,
                                   DataSourceObserver* observer)
    : data_source_(data_source), observer_(observer) {
  data_source_->AddObserver(observer_);
}

ScopedDataSource::~ScopedDataSource() {
  data_source_->RemoveObserver(observer_);
}

DataSource::DataSource(DataSourceDelegate* delegate)
    : delegate_(delegate), finished_(false) {}

DataSource::~DataSource() {
  delegate_->OnDataSourceDestroying(this);
  for (DataSourceObserver& observer : observers_) {
    observer.OnDataSourceDestroying(this);
  }
}

void DataSource::AddObserver(DataSourceObserver* observer) {
  observers_.AddObserver(observer);
}

void DataSource::RemoveObserver(DataSourceObserver* observer) {
  observers_.RemoveObserver(observer);
}

void DataSource::Offer(const std::string& mime_type) {
  mime_types_.insert(mime_type);
}

void DataSource::SetActions(const base::flat_set<DndAction>& dnd_actions) {
  dnd_actions_ = dnd_actions;
}

void DataSource::Target(const base::Optional<std::string>& mime_type) {
  delegate_->OnTarget(mime_type);
}

void DataSource::Action(DndAction action) {
  delegate_->OnAction(action);
}

void DataSource::DndDropPerformed() {
  delegate_->OnDndDropPerformed();
}

void DataSource::Cancelled() {
  finished_ = true;
  read_data_weak_ptr_factory_.InvalidateWeakPtrs();
  delegate_->OnCancelled();
}

void DataSource::DndFinished() {
  finished_ = true;
  read_data_weak_ptr_factory_.InvalidateWeakPtrs();
  delegate_->OnDndFinished();
}

void DataSource::ReadDataForTesting(const std::string& mime_type,
                                    ReadDataCallback callback) {
  ReadData(mime_type, std::move(callback), base::DoNothing());
}

void DataSource::ReadData(const std::string& mime_type,
                          ReadDataCallback callback,
                          base::OnceClosure failure_callback) {
  // This DataSource does not contain the requested MIME type.
  if (mime_type.empty() || !mime_types_.count(mime_type) || finished_) {
    std::move(failure_callback).Run();
    return;
  }

  base::ScopedFD read_fd;
  base::ScopedFD write_fd;
  PCHECK(base::CreatePipe(&read_fd, &write_fd));
  delegate_->OnSend(mime_type, std::move(write_fd));

  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE,
      {base::MayBlock(), base::TaskPriority::USER_BLOCKING,
       base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
      base::BindOnce(&ReadDataOnWorkerThread, std::move(read_fd)),
      base::BindOnce(
          &DataSource::OnDataRead, read_data_weak_ptr_factory_.GetWeakPtr(),
          std::move(callback), mime_type, std::move(failure_callback)));
}

void DataSource::OnDataRead(ReadDataCallback callback,
                            const std::string& mime_type,
                            base::OnceClosure failure_callback,
                            const base::Optional<std::vector<uint8_t>>& data) {
  if (!data) {
    std::move(failure_callback).Run();
    return;
  }
  std::move(callback).Run(mime_type, *data);
}

void DataSource::GetDataForPreferredMimeTypes(
    ReadTextDataCallback text_reader,
    ReadDataCallback rtf_reader,
    ReadTextDataCallback html_reader,
    ReadDataCallback image_reader,
    ReadDataCallback filenames_reader,
    base::RepeatingClosure failure_callback) {
  std::string text_mime, rtf_mime, html_mime, image_mime, filenames_mime;

  int text_rank = std::numeric_limits<int>::max();
  int html_rank = std::numeric_limits<int>::max();
  int image_rank = std::numeric_limits<int>::max();

  for (auto mime_type : mime_types_) {
    if (net::MatchesMimeType(std::string(kTextPlain), mime_type) ||
        mime_type == ui::kMimeTypeLinuxUtf8String) {
      if (text_reader.is_null())
        continue;

      std::string charset;
      charset = GetCharset(mime_type);
      int new_rank = GetCharsetRank(charset);
      if (new_rank < text_rank) {
        text_mime = mime_type;
        text_rank = new_rank;
      }
    } else if (net::MatchesMimeType(std::string(kTextRTF), mime_type)) {
      if (rtf_reader.is_null())
        continue;

      // The RTF MIME type will never have a character set because it only uses
      // 7-bit bytes and stores character set information internally.
      rtf_mime = mime_type;
    } else if (net::MatchesMimeType(std::string(kTextHTML), mime_type)) {
      if (html_reader.is_null())
        continue;

      auto charset = GetCharset(mime_type);
      int new_rank = GetCharsetRank(charset);
      if (new_rank < html_rank) {
        html_mime = mime_type;
        html_rank = new_rank;
      }
    } else if (blink::IsSupportedImageMimeType(mime_type)) {
      if (image_reader.is_null())
        continue;

      int new_rank = GetImageTypeRank(mime_type);
      if (new_rank < image_rank) {
        image_mime = mime_type;
        image_rank = new_rank;
      }
    } else if (net::MatchesMimeType(std::string(kTextUriList), mime_type)) {
      if (filenames_reader.is_null())
        continue;

      filenames_mime = mime_type;
    }
  }

  ReadData(text_mime,
           base::BindOnce(&DataSource::OnTextRead,
                          read_data_weak_ptr_factory_.GetWeakPtr(),
                          std::move(text_reader)),
           failure_callback);
  ReadData(rtf_mime, std::move(rtf_reader), failure_callback);
  ReadData(html_mime,
           base::BindOnce(&DataSource::OnTextRead,
                          read_data_weak_ptr_factory_.GetWeakPtr(),
                          std::move(html_reader)),
           failure_callback);
  ReadData(image_mime, std::move(image_reader), failure_callback);
  ReadData(filenames_mime, std::move(filenames_reader), failure_callback);
}

void DataSource::OnTextRead(ReadTextDataCallback callback,
                            const std::string& mime_type,
                            const std::vector<uint8_t>& data) {
  std::u16string output = CodepageToUTF16(data, GetCharset(mime_type));
  std::move(callback).Run(mime_type, std::move(output));
}

bool DataSource::CanBeDataSourceForCopy(Surface* surface) const {
  return delegate_->CanAcceptDataEventsForSurface(surface);
}

}  // namespace exo
