// Copyright 2020 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/sane_client_fake.h"

#include <algorithm>
#include <map>
#include <utility>

#include <chromeos/dbus/service_constants.h>

#include "lorgnette/dbus_adaptors/org.chromium.lorgnette.Manager.h"

static const char* kDbusDomain = brillo::errors::dbus::kDomain;

namespace lorgnette {

std::unique_ptr<SaneDevice> SaneClientFake::ConnectToDeviceInternal(
    brillo::ErrorPtr* error, const std::string& device_name) {
  if (devices_.count(device_name) > 0) {
    auto ptr = std::move(devices_[device_name]);
    devices_.erase(device_name);
    return ptr;
  }

  brillo::Error::AddTo(error, FROM_HERE, kDbusDomain, kManagerServiceError,
                       "No device");
  return nullptr;
}

void SaneClientFake::SetListDevicesResult(bool value) {
  list_devices_result_ = value;
}

void SaneClientFake::AddDevice(const std::string& name,
                               const std::string& manufacturer,
                               const std::string& model,
                               const std::string& type) {
  ScannerInfo info;
  info.set_name(name);
  info.set_manufacturer(manufacturer);
  info.set_model(model);
  info.set_type(type);
  scanners_.push_back(info);
}

void SaneClientFake::RemoveDevice(const std::string& name) {
  for (auto it = scanners_.begin(); it != scanners_.end(); it++) {
    if (it->name() == name) {
      scanners_.erase(it);
    }
  }
}

void SaneClientFake::SetDeviceForName(const std::string& device_name,
                                      std::unique_ptr<SaneDeviceFake> device) {
  devices_.emplace(device_name, std::move(device));
}

SaneDeviceFake::SaneDeviceFake()
    : resolution_(100),
      start_scan_result_(SANE_STATUS_GOOD),
      read_scan_data_result_(SANE_STATUS_GOOD),
      scan_running_(false),
      cancelled_(false) {}

SaneDeviceFake::~SaneDeviceFake() {}

base::Optional<ValidOptionValues> SaneDeviceFake::GetValidOptionValues(
    brillo::ErrorPtr* error) {
  if (!values_.has_value()) {
    brillo::Error::AddTo(error, FROM_HERE, kDbusDomain, kManagerServiceError,
                         "No option values");
  }

  return values_;
}

bool SaneDeviceFake::SetScanResolution(brillo::ErrorPtr*, int resolution) {
  resolution_ = resolution;
  return true;
}

bool SaneDeviceFake::SetDocumentSource(brillo::ErrorPtr*,
                                       const std::string& source_name) {
  source_name_ = source_name;
  return true;
}

bool SaneDeviceFake::SetColorMode(brillo::ErrorPtr*, ColorMode) {
  return true;
}

bool SaneDeviceFake::SetScanRegion(brillo::ErrorPtr* error, const ScanRegion&) {
  return true;
}

SANE_Status SaneDeviceFake::StartScan(brillo::ErrorPtr* error) {
  // Don't allow starting the next page of the scan if we haven't completed the
  // previous one.
  if (scan_running_ && current_page_ < scan_data_.size() &&
      scan_data_offset_ < scan_data_[current_page_].size()) {
    brillo::Error::AddTo(error, FROM_HERE, kDbusDomain, kManagerServiceError,
                         "Scan is already running");
    return SANE_STATUS_DEVICE_BUSY;
  }

  if (cancelled_) {
    return SANE_STATUS_CANCELLED;
  }

  if (start_scan_result_ != SANE_STATUS_GOOD) {
    return start_scan_result_;
  }

  if (scan_running_ && current_page_ + 1 == scan_data_.size()) {
    // No more scan data left.
    return SANE_STATUS_NO_DOCS;
  } else if (scan_running_) {
    current_page_++;
    scan_data_offset_ = 0;
  } else {
    scan_running_ = true;
    current_page_ = 0;
    cancelled_ = false;
    scan_data_offset_ = 0;
  }

  return SANE_STATUS_GOOD;
}

base::Optional<ScanParameters> SaneDeviceFake::GetScanParameters(
    brillo::ErrorPtr* error) {
  if (!params_.has_value()) {
    brillo::Error::AddTo(error, FROM_HERE, kDbusDomain, kManagerServiceError,
                         "No parameters");
  }

  return params_;
}

SANE_Status SaneDeviceFake::ReadScanData(brillo::ErrorPtr* error,
                                         uint8_t* buf,
                                         size_t count,
                                         size_t* read_out) {
  if (!scan_running_) {
    brillo::Error::AddTo(error, FROM_HERE, kDbusDomain, kManagerServiceError,
                         "Scan not running");
    return SANE_STATUS_INVAL;
  }

  if (cancelled_) {
    scan_running_ = false;
    return SANE_STATUS_CANCELLED;
  }

  if (read_scan_data_result_ != SANE_STATUS_GOOD) {
    brillo::Error::AddTo(error, FROM_HERE, kDbusDomain, kManagerServiceError,
                         "Reading data failed");
    return read_scan_data_result_;
  }

  if (current_page_ >= scan_data_.size()) {
    scan_running_ = false;
    return SANE_STATUS_NO_DOCS;
  }

  const std::vector<uint8_t>& page = scan_data_[current_page_];
  if (scan_data_offset_ >= page.size()) {
    *read_out = 0;
    return SANE_STATUS_EOF;
  }

  size_t to_copy = std::min(count, page.size() - scan_data_offset_);
  memcpy(buf, page.data() + scan_data_offset_, to_copy);
  *read_out = to_copy;

  scan_data_offset_ += to_copy;
  return SANE_STATUS_GOOD;
}

bool SaneDeviceFake::CancelScan(brillo::ErrorPtr* error) {
  if (!scan_running_) {
    brillo::Error::AddTo(error, FROM_HERE, kDbusDomain, kManagerServiceError,
                         "Scan not running");
    return false;
  }

  cancelled_ = true;
  return true;
}

void SaneDeviceFake::SetValidOptionValues(
    const base::Optional<ValidOptionValues>& values) {
  values_ = values;
}

void SaneDeviceFake::SetStartScanResult(SANE_Status status) {
  start_scan_result_ = status;
}

void SaneDeviceFake::SetScanParameters(
    const base::Optional<ScanParameters>& params) {
  params_ = params;
}

void SaneDeviceFake::SetReadScanDataResult(SANE_Status result) {
  read_scan_data_result_ = result;
}

void SaneDeviceFake::SetScanData(
    const std::vector<std::vector<uint8_t>>& scan_data) {
  scan_data_ = scan_data;
}

}  // namespace lorgnette
