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

#include "chromeos/ui/clipboard_history/clipboard_history_util.h"

#include <string_view>

#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/strings/utf_string_conversions.h"
#include "chromeos/ui/base/file_icon_util.h"
#include "chromeos/ui/clipboard_history/clipboard_history_types.h"
#include "chromeos/ui/vector_icons/vector_icons.h"
#include "components/vector_icons/vector_icons.h"
#include "ui/base/models/image_model.h"
#include "ui/base/ui_base_features.h"
#include "url/gurl.h"

namespace gfx {
struct VectorIcon;
}  // namespace gfx

namespace chromeos::clipboard_history {

namespace {

// The DIP size of a menu item icon that indicates the clipboard data format.
constexpr int kIconSize = 20;

QueryItemDescriptorsImpl& GetQueryItemDescriptorsImpl() {
  static base::NoDestructor<QueryItemDescriptorsImpl>
      query_item_descriptors_impl;
  return *query_item_descriptors_impl;
}

PasteClipboardItemByIdImpl& GetPasteClipboardItemByIdImpl() {
  static base::NoDestructor<PasteClipboardItemByIdImpl> paste_item_by_id_impl;
  return *paste_item_by_id_impl;
}

}  // namespace

bool IsUrl(std::u16string_view text) {
  return GURL(text).is_valid();
}

void SetQueryItemDescriptorsImpl(QueryItemDescriptorsImpl impl) {
  QueryItemDescriptorsImpl& old_impl = GetQueryItemDescriptorsImpl();
  CHECK(old_impl.is_null() || impl.is_null());
  old_impl = impl;
}

QueryItemDescriptorsImpl::ResultType QueryItemDescriptors() {
  // `SetQueryItemDescriptorsImpl()` may not have been called in unit tests.
  if (auto& query_callback = GetQueryItemDescriptorsImpl()) {
    return query_callback.Run();
  }

  return QueryItemDescriptorsImpl::ResultType();
}

void SetPasteClipboardItemByIdImpl(PasteClipboardItemByIdImpl impl) {
  PasteClipboardItemByIdImpl& old_impl = GetPasteClipboardItemByIdImpl();
  CHECK(old_impl.is_null() || impl.is_null());
  old_impl = impl;
}

void PasteClipboardItemById(const base::UnguessableToken& id,
                            int event_flags,
                            ShowSource paste_source) {
  // `SetPasteClipboardItemByIdImpl()` may not have been called in unit tests.
  if (auto& paste_callback = GetPasteClipboardItemByIdImpl()) {
    paste_callback.Run(id, event_flags, paste_source);
  }
}

ui::ImageModel GetIconForDescriptor(const ItemDescriptor& descriptor) {
  const gfx::VectorIcon* icon = nullptr;
  switch (descriptor.display_format) {
    case DisplayFormat::kText:
      // TODO(http://b/275629173): Consider a new display format for URLs.
      icon = IsUrl(descriptor.display_text)
                 ? &(::features::IsRoundedIconsEnabled()
                         ? vector_icons::kLinkIcon
                         : vector_icons::kLinkOldIcon)
                 : &kTextIcon;
      break;
    case DisplayFormat::kPng:
      icon = &kFiletypeImageIcon;
      break;
    case DisplayFormat::kHtml:
      icon =
          &(::features::IsRoundedIconsEnabled() ? vector_icons::kCodeIcon
                                                : vector_icons::kCodeOldIcon);
      break;
    case DisplayFormat::kFile: {
      // If `display_text` is the name of a single file, use the icon
      // corresponding to the file type, if any; otherwise, use a generic
      // multi-file icon.
      icon = descriptor.file_count == 1
                 ? &chromeos::GetIconForPath(base::FilePath(
                       base::UTF16ToUTF8(descriptor.display_text)))
                 : &(::features::IsRoundedIconsEnabled()
                         ? vector_icons::kContentCopyIcon
                         : vector_icons::kContentCopyOldIcon);
      break;
    }
    case DisplayFormat::kUnknown:
      NOTREACHED();
  }

  if (icon) {
    // TODO(b/278109818): Double-check the icon color.
    return ui::ImageModel::FromVectorIcon(*icon,
                                          /*color_id=*/ui::kColorSysSecondary,
                                          kIconSize);
  }

  NOTREACHED();
}

}  // namespace chromeos::clipboard_history
