// Copyright (c) 2013 The Chromium OS 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 "lorgnette/manager.h"

#include <map>
#include <string>

#include <base/memory/scoped_ptr.h>
#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <chromeos/dbus/service_constants.h>
#include <chromeos/variant_dictionary.h>
#include <chromeos/process_mock.h>
#include <gtest/gtest.h>
#include <metrics/metrics_library_mock.h>

using base::ScopedFD;
using chromeos::VariantDictionary;
using std::map;
using std::string;
using testing::_;
using testing::InSequence;
using testing::Return;

namespace lorgnette {

class ManagerTest : public testing::Test {
 public:
  ManagerTest()
     : input_scoped_fd_(kInputPipeFd),
       output_scoped_fd_(kOutputPipeFd),
       manager_(base::Callback<void()>()),
       metrics_library_(new MetricsLibraryMock) {
    manager_.metrics_library_.reset(metrics_library_);
  }

  virtual void TearDown() {
    // The fds that we have handed to these ScopedFD are not real, so we
    // must prevent our scoped fds from calling close() on them.
    int fd = input_scoped_fd_.release();
    CHECK(fd == kInvalidFd || fd == kInputPipeFd);
    fd = output_scoped_fd_.release();
    CHECK(fd == kInvalidFd || fd == kOutputPipeFd);
  }

 protected:
  static const char kDeviceName[];
  static const char kMode[];
  static const int kInvalidFd;
  static const int kInputPipeFd;
  static const int kOutputFd;
  static const int kOutputPipeFd;
  static const int kResolution;

  static void RunListScannersProcess(int fd, chromeos::Process* process) {
    Manager::RunListScannersProcess(fd, process);
  }

  void RunScanImageProcess(const string& device_name,
                           int out_fd,
                           base::ScopedFD* input_scoped_fd,
                           base::ScopedFD* output_scoped_fd,
                           const VariantDictionary& scan_properties,
                           chromeos::Process* scan_process,
                           chromeos::Process* convert_process,
                           chromeos::ErrorPtr* error) {
    manager_.RunScanImageProcess(device_name,
                                 out_fd,
                                 input_scoped_fd,
                                 output_scoped_fd,
                                 scan_properties,
                                 scan_process,
                                 convert_process,
                                 error);
  }

  static void ExpectStartScan(const char* mode,
                              int resolution,
                              chromeos::ProcessMock* scan_process,
                              chromeos::ProcessMock* convert_process) {
    EXPECT_CALL(*scan_process, AddArg(GetScanImagePath()));
    EXPECT_CALL(*scan_process, AddArg("-d"));
    EXPECT_CALL(*scan_process, AddArg(kDeviceName));
    if (mode) {
      EXPECT_CALL(*scan_process, AddArg("--mode"));
      EXPECT_CALL(*scan_process, AddArg(mode));
    }
    if (resolution) {
      const string kResolutionString(base::IntToString(resolution));
      EXPECT_CALL(*scan_process, AddArg("--resolution"));
      EXPECT_CALL(*scan_process, AddArg(kResolutionString));
    }
    EXPECT_CALL(*scan_process, BindFd(kOutputPipeFd, STDOUT_FILENO));
    EXPECT_CALL(*convert_process, AddArg(GetScanConverterPath()));
    EXPECT_CALL(*convert_process, BindFd(kInputPipeFd, STDIN_FILENO));
    EXPECT_CALL(*convert_process, BindFd(kOutputFd, STDOUT_FILENO));
    EXPECT_CALL(*convert_process, Start());
    EXPECT_CALL(*scan_process, Start());
  }

  static Manager::ScannerInfo ScannerInfoFromString(
      const std::string& scanner_info_string) {
    return Manager::ScannerInfoFromString(scanner_info_string);
  }

  static std::string GetScanConverterPath() {
    return Manager::kScanConverterPath;
  }
  static std::string GetScanImagePath() { return Manager::kScanImagePath; }
  static std::string GetScanImageFromattedDeviceListCmd() {
    return Manager::kScanImageFormattedDeviceListCmd;
  }

  ScopedFD input_scoped_fd_;
  ScopedFD output_scoped_fd_;
  Manager manager_;
  MetricsLibraryMock* metrics_library_;  // Owned by manager_.
};

// kInvalidFd must equal to base::internal::ScopedFDCloseTraits::InvalidValue().
const int ManagerTest::kInvalidFd = -1;
const int ManagerTest::kInputPipeFd = 123;
const int ManagerTest::kOutputFd = 456;
const int ManagerTest::kOutputPipeFd = 789;
const char ManagerTest::kDeviceName[] = "scanner";
const int ManagerTest::kResolution = 300;
const char ManagerTest::kMode[] = "Color";

MATCHER_P(IsDbusErrorStartingWith, message, "") {
  return arg != nullptr &&
      arg->GetDomain() == chromeos::errors::dbus::kDomain &&
      arg->GetCode() == kManagerServiceError &&
      StartsWithASCII(arg->GetMessage(), message, false);
}

TEST_F(ManagerTest, RunListScannersProcess) {
  chromeos::ProcessMock process;
  const int kFd = 123;
  InSequence seq;
  EXPECT_CALL(process, AddArg(GetScanImagePath()));
  EXPECT_CALL(process, AddArg(GetScanImageFromattedDeviceListCmd()));
  EXPECT_CALL(process, BindFd(kFd, STDOUT_FILENO));
  EXPECT_CALL(process, Run());
  RunListScannersProcess(kFd, &process);
}

TEST_F(ManagerTest, RunScanImageProcessSuccess) {
  VariantDictionary props{
      {"Mode", string{kMode}},
      {"Resolution", uint32_t{kResolution}}
  };
  chromeos::ProcessMock scan_process;
  chromeos::ProcessMock convert_process;
  InSequence seq;
  ExpectStartScan(kMode,
                  kResolution,
                  &scan_process,
                  &convert_process);
  EXPECT_CALL(scan_process, Wait()).WillOnce(Return(0));
  EXPECT_CALL(*metrics_library_,
              SendEnumToUMA(Manager::kMetricScanResult,
                            Manager::kBooleanMetricSuccess,
                            Manager::kBooleanMetricMax));
  EXPECT_CALL(convert_process, Wait()).WillOnce(Return(0));
  EXPECT_CALL(*metrics_library_,
              SendEnumToUMA(Manager::kMetricConverterResult,
                            Manager::kBooleanMetricSuccess,
                            Manager::kBooleanMetricMax));
  chromeos::ErrorPtr error;
  RunScanImageProcess(kDeviceName,
                      kOutputFd,
                      &input_scoped_fd_,
                      &output_scoped_fd_,
                      props,
                      &scan_process,
                      &convert_process,
                      &error);
  EXPECT_EQ(kInvalidFd, input_scoped_fd_.get());
  EXPECT_EQ(kInvalidFd, output_scoped_fd_.get());
  EXPECT_EQ(nullptr, error.get());
}

TEST_F(ManagerTest, RunScanImageProcessInvalidArgument) {
  const char kInvalidArgument[] = "InvalidArgument";
  VariantDictionary props{{kInvalidArgument, ""}};
  chromeos::ProcessMock scan_process;
  chromeos::ProcessMock convert_process;
  // For "scanimage", "-d", "<device name>".
  EXPECT_CALL(scan_process, AddArg(_)).Times(3);
  EXPECT_CALL(convert_process, AddArg(_)).Times(0);
  EXPECT_CALL(convert_process, Start()).Times(0);
  EXPECT_CALL(scan_process, Start()).Times(0);
  chromeos::ErrorPtr error;
  RunScanImageProcess("", 0, nullptr, nullptr, props, &scan_process,
                      &convert_process, &error);

  // Expect that the pipe fds have not been released.
  EXPECT_EQ(kInputPipeFd, input_scoped_fd_.get());
  EXPECT_EQ(kOutputPipeFd, output_scoped_fd_.get());

  EXPECT_THAT(error, IsDbusErrorStartingWith(
      base::StringPrintf("Invalid scan parameter %s", kInvalidArgument)));
}

TEST_F(ManagerTest, RunScanImageInvalidModeArgument) {
  const char kBadMode[] = "Raytrace";
  VariantDictionary props{{"Mode", string{kBadMode}}};
  chromeos::ProcessMock scan_process;
  chromeos::ProcessMock convert_process;
  // For "scanimage", "-d", "<device name>".
  EXPECT_CALL(scan_process, AddArg(_)).Times(3);
  EXPECT_CALL(convert_process, AddArg(_)).Times(0);
  EXPECT_CALL(convert_process, Start()).Times(0);
  EXPECT_CALL(scan_process, Start()).Times(0);
  chromeos::ErrorPtr error;
  RunScanImageProcess(kDeviceName,
                      kOutputFd,
                      &input_scoped_fd_,
                      &output_scoped_fd_,
                      props,
                      &scan_process,
                      &convert_process,
                      &error);

  // Expect that the pipe fds have not been released.
  EXPECT_EQ(kInputPipeFd, input_scoped_fd_.get());
  EXPECT_EQ(kOutputPipeFd, output_scoped_fd_.get());

  EXPECT_THAT(error, IsDbusErrorStartingWith(
      base::StringPrintf("Invalid mode parameter %s", kBadMode)));
}

TEST_F(ManagerTest, RunScanImageProcessCaptureFailure) {
  VariantDictionary props{
      {"Mode", string{kMode}},
      {"Resolution", uint32_t{kResolution}}
  };
  chromeos::ProcessMock scan_process;
  chromeos::ProcessMock convert_process;
  InSequence seq;
  ExpectStartScan(kMode,
                  kResolution,
                  &scan_process,
                  &convert_process);
  const int kErrorResult = 999;
  EXPECT_CALL(scan_process, Wait()).WillOnce(Return(kErrorResult));
  EXPECT_CALL(*metrics_library_,
              SendEnumToUMA(Manager::kMetricScanResult,
                            Manager::kBooleanMetricFailure,
                            Manager::kBooleanMetricMax));
  EXPECT_CALL(convert_process, Kill(SIGKILL, 1));
  EXPECT_CALL(convert_process, Wait()).Times(0);
  chromeos::ErrorPtr error;
  RunScanImageProcess(kDeviceName,
                      kOutputFd,
                      &input_scoped_fd_,
                      &output_scoped_fd_,
                      props,
                      &scan_process,
                      &convert_process,
                      &error);
  EXPECT_EQ(kInvalidFd, input_scoped_fd_.get());
  EXPECT_EQ(kInvalidFd, output_scoped_fd_.get());
  EXPECT_THAT(error, IsDbusErrorStartingWith(
      base::StringPrintf("Scan process exited with result %d", kErrorResult)));
}

TEST_F(ManagerTest, RunScanImageProcessConvertFailure) {
  VariantDictionary props{
      {"Mode", string{kMode}},
      {"Resolution", uint32_t{kResolution}}
  };
  chromeos::ProcessMock scan_process;
  chromeos::ProcessMock convert_process;
  InSequence seq;
  ExpectStartScan(kMode,
                  kResolution,
                  &scan_process,
                  &convert_process);
  EXPECT_CALL(scan_process, Wait()).WillOnce(Return(0));
  EXPECT_CALL(*metrics_library_,
              SendEnumToUMA(Manager::kMetricScanResult,
                            Manager::kBooleanMetricSuccess,
                            Manager::kBooleanMetricMax));
  const int kErrorResult = 111;
  EXPECT_CALL(convert_process, Wait()).WillOnce(Return(kErrorResult));
  EXPECT_CALL(*metrics_library_,
              SendEnumToUMA(Manager::kMetricConverterResult,
                            Manager::kBooleanMetricFailure,
                            Manager::kBooleanMetricMax));
  chromeos::ErrorPtr error;
  RunScanImageProcess(kDeviceName,
                      kOutputFd,
                      &input_scoped_fd_,
                      &output_scoped_fd_,
                      props,
                      &scan_process,
                      &convert_process,
                      &error);
  EXPECT_EQ(kInvalidFd, input_scoped_fd_.get());
  EXPECT_EQ(kInvalidFd, output_scoped_fd_.get());
  EXPECT_THAT(error, IsDbusErrorStartingWith(
      base::StringPrintf("Image converter process failed with result %d",
                         kErrorResult)));
}

TEST_F(ManagerTest, ScannerInfoFromString) {
  EXPECT_TRUE(ScannerInfoFromString("").empty());
  EXPECT_TRUE(ScannerInfoFromString("one").empty());
  EXPECT_TRUE(ScannerInfoFromString("one%two").empty());
  EXPECT_TRUE(ScannerInfoFromString("one%two%three").empty());
  const char kDevice0[] = "device0";
  const char kDevice1[] = "device1";
  const char kManufacturer0[] = "rayban";
  const char kManufacturer1[] = "oakley";
  const char kModel0[] = "model0";
  const char kModel1[] = "model1";
  const char kType0[] = "type0";
  const char kType1[] = "type1";
  const string kInputString(base::StringPrintf(
      "one\n"
      "%s%%%s%%%s%%%s\n"
      "one%%two\n"
      "%s%%%s%%%s%%%s\n"
      "one%%two%%three\n"
      "one%%two%%three%%four%%five\n",
      kDevice0, kManufacturer0, kModel0, kType0,
      kDevice1, kManufacturer1, kModel1, kType1));
  Manager::ScannerInfo scan_info = ScannerInfoFromString(kInputString);
  EXPECT_EQ(2, scan_info.size());
  EXPECT_TRUE(ContainsKey(scan_info, kDevice0));
  EXPECT_EQ(3, scan_info[kDevice0].size());
  EXPECT_STREQ(kManufacturer0, scan_info[kDevice0]["Manufacturer"].c_str());
  EXPECT_STREQ(kModel0, scan_info[kDevice0]["Model"].c_str());
  EXPECT_STREQ(kType0, scan_info[kDevice0]["Type"].c_str());

  EXPECT_TRUE(ContainsKey(scan_info, kDevice1));
  EXPECT_EQ(3, scan_info[kDevice1].size());
  EXPECT_STREQ(kManufacturer1, scan_info[kDevice1]["Manufacturer"].c_str());
  EXPECT_STREQ(kModel1, scan_info[kDevice1]["Model"].c_str());
  EXPECT_STREQ(kType1, scan_info[kDevice1]["Type"].c_str());
}

}  // namespace lorgnette
