// Copyright 2018 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/printing/browser/printer_capabilities.h"

#include <memory>

#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/stl_util.h"
#include "base/values.h"
#include "content/public/test/browser_task_environment.h"
#include "printing/backend/test_print_backend.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/size.h"

namespace printing {

using base::Value;

namespace {

const char kDpi[] = "dpi";

}  // namespace

class PrinterCapabilitiesTest : public testing::Test {
 public:
  PrinterCapabilitiesTest() {}
  ~PrinterCapabilitiesTest() override {}

 protected:
  void SetUp() override {
    test_backend_ = base::MakeRefCounted<TestPrintBackend>();
    PrintBackend::SetPrintBackendForTesting(test_backend_.get());
  }

  void TearDown() override { test_backend_ = nullptr; }

  TestPrintBackend* print_backend() { return test_backend_.get(); }

 private:
  content::BrowserTaskEnvironment task_environment_;
  scoped_refptr<TestPrintBackend> test_backend_;
};

// Verify that we don't crash for a missing printer and a nullptr is never
// returned.
TEST_F(PrinterCapabilitiesTest, NonNullForMissingPrinter) {
  std::string printer_name = "missing_printer";
  PrinterBasicInfo basic_info;
  PrinterSemanticCapsAndDefaults::Papers no_additional_papers;

  base::Value settings_dictionary =
      GetSettingsOnBlockingPool(printer_name, basic_info, no_additional_papers,
                                /* has_secure_protocol */ false, nullptr);

  ASSERT_FALSE(settings_dictionary.DictEmpty());
}

TEST_F(PrinterCapabilitiesTest, ProvidedCapabilitiesUsed) {
  std::string printer_name = "test_printer";
  PrinterBasicInfo basic_info;
  PrinterSemanticCapsAndDefaults::Papers no_additional_papers;

  // Set a capability and add a valid printer.
  auto caps = std::make_unique<PrinterSemanticCapsAndDefaults>();
  caps->dpis = {{600, 600}};
  print_backend()->AddValidPrinter(printer_name, std::move(caps));

  base::Value settings_dictionary = GetSettingsOnBlockingPool(
      printer_name, basic_info, no_additional_papers,
      /* has_secure_protocol */ false, print_backend());

  // Verify settings were created.
  ASSERT_FALSE(settings_dictionary.DictEmpty());

  // Verify capabilities dict exists and has 2 entries. (printer and version)
  base::Value* cdd = settings_dictionary.FindKeyOfType(
      kSettingCapabilities, base::Value::Type::DICTIONARY);
  ASSERT_TRUE(cdd);
  EXPECT_EQ(2U, cdd->DictSize());

  // Read the CDD for the "dpi" attribute.
  base::Value* caps_dict =
      cdd->FindKeyOfType(kPrinter, base::Value::Type::DICTIONARY);
  ASSERT_TRUE(caps_dict);
  EXPECT_TRUE(caps_dict->FindKey(kDpi));
}

// Ensure that the capabilities dictionary is present but empty if the backend
// doesn't return capabilities.
TEST_F(PrinterCapabilitiesTest, NullCapabilitiesExcluded) {
  std::string printer_name = "test_printer";
  PrinterBasicInfo basic_info;
  PrinterSemanticCapsAndDefaults::Papers no_additional_papers;

  // Return false when attempting to retrieve capabilities.
  print_backend()->AddValidPrinter(printer_name, nullptr);

  base::Value settings_dictionary = GetSettingsOnBlockingPool(
      printer_name, basic_info, no_additional_papers,
      /* has_secure_protocol */ false, print_backend());

  // Verify settings were created.
  ASSERT_FALSE(settings_dictionary.DictEmpty());

  // Verify that capabilities is an empty dictionary.
  base::Value* caps_dict = settings_dictionary.FindKeyOfType(
      kSettingCapabilities, base::Value::Type::DICTIONARY);
  ASSERT_TRUE(caps_dict);
  EXPECT_TRUE(caps_dict->DictEmpty());
}

TEST_F(PrinterCapabilitiesTest, AdditionalPapers) {
  std::string printer_name = "test_printer";
  PrinterBasicInfo basic_info;

  // Set a capability and add a valid printer.
  auto caps = std::make_unique<PrinterSemanticCapsAndDefaults>();
  caps->dpis = {{600, 600}};
  print_backend()->AddValidPrinter(printer_name, std::move(caps));

  // Add some more paper sizes.
  PrinterSemanticCapsAndDefaults::Papers additional_papers;
  additional_papers.push_back({"foo", "vendor", {200, 300}});
  additional_papers.push_back({"bar", "vendor", {600, 600}});

  base::Value settings_dictionary = GetSettingsOnBlockingPool(
      printer_name, basic_info, additional_papers,
      /* has_secure_protocol */ false, print_backend());

  // Verify settings were created.
  ASSERT_FALSE(settings_dictionary.DictEmpty());

  // Verify there is a CDD with a printer entry.
  const Value* cdd = settings_dictionary.FindKeyOfType(kSettingCapabilities,
                                                       Value::Type::DICTIONARY);
  ASSERT_TRUE(cdd);
  const Value* printer = cdd->FindKeyOfType(kPrinter, Value::Type::DICTIONARY);
  ASSERT_TRUE(printer);

  // Verify there are 2 paper sizes.
  const Value* media_size =
      printer->FindKeyOfType("media_size", Value::Type::DICTIONARY);
  ASSERT_TRUE(media_size);
  const Value* media_option =
      media_size->FindKeyOfType("option", Value::Type::LIST);
  ASSERT_TRUE(media_option);
  const auto& list = media_option->GetList();
  ASSERT_EQ(2U, list.size());
  ASSERT_TRUE(list[0].is_dict());
  ASSERT_TRUE(list[1].is_dict());

  // Verify the 2 paper sizes are the ones in |additional_papers|.
  const Value* name;
  const Value* vendor;
  const Value* width;
  const Value* height;

  name = list[0].FindKeyOfType("custom_display_name", Value::Type::STRING);
  ASSERT_TRUE(name);
  EXPECT_EQ("foo", name->GetString());
  vendor = list[0].FindKeyOfType("vendor_id", Value::Type::STRING);
  ASSERT_TRUE(vendor);
  EXPECT_EQ("vendor", vendor->GetString());
  width = list[0].FindKeyOfType("width_microns", Value::Type::INTEGER);
  ASSERT_TRUE(width);
  EXPECT_EQ(200, width->GetInt());
  height = list[0].FindKeyOfType("height_microns", Value::Type::INTEGER);
  ASSERT_TRUE(height);
  EXPECT_EQ(300, height->GetInt());

  name = list[1].FindKeyOfType("custom_display_name", Value::Type::STRING);
  ASSERT_TRUE(name);
  EXPECT_EQ("bar", name->GetString());
  vendor = list[1].FindKeyOfType("vendor_id", Value::Type::STRING);
  ASSERT_TRUE(vendor);
  EXPECT_EQ("vendor", vendor->GetString());
  width = list[1].FindKeyOfType("width_microns", Value::Type::INTEGER);
  ASSERT_TRUE(width);
  EXPECT_EQ(600, width->GetInt());
  height = list[1].FindKeyOfType("height_microns", Value::Type::INTEGER);
  ASSERT_TRUE(height);
  EXPECT_EQ(600, height->GetInt());
}

#if defined(OS_CHROMEOS)
TEST_F(PrinterCapabilitiesTest, HasNotSecureProtocol) {
  std::string printer_name = "test_printer";
  PrinterBasicInfo basic_info;
  PrinterSemanticCapsAndDefaults::Papers no_additional_papers;
  bool has_secure_protocol = false;

  // Set a capability and add a valid printer.
  auto caps = std::make_unique<PrinterSemanticCapsAndDefaults>();
  caps->pin_supported = true;
  print_backend()->AddValidPrinter(printer_name, std::move(caps));

  base::Value settings_dictionary =
      GetSettingsOnBlockingPool(printer_name, basic_info, no_additional_papers,
                                has_secure_protocol, print_backend());

  // Verify settings were created.
  ASSERT_FALSE(settings_dictionary.DictEmpty());

  // Verify there is a CDD with a printer entry.
  const Value* cdd = settings_dictionary.FindKeyOfType(kSettingCapabilities,
                                                       Value::Type::DICTIONARY);
  ASSERT_TRUE(cdd);
  const Value* printer = cdd->FindKeyOfType(kPrinter, Value::Type::DICTIONARY);
  ASSERT_TRUE(printer);

  // Verify that pin is not supported.
  const Value* pin = printer->FindKeyOfType("pin", Value::Type::DICTIONARY);
  ASSERT_TRUE(pin);
  base::Optional<bool> pin_supported = pin->FindBoolKey("supported");
  ASSERT_TRUE(pin_supported.has_value());
  ASSERT_FALSE(pin_supported.value());
}
#endif  // defined(OS_CHROMEOS)

}  // namespace printing
