// Copyright (c) 2012 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 "chromeos/dbus/fake_update_engine_client.h"

#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"

namespace chromeos {

FakeUpdateEngineClient::FakeUpdateEngineClient()
    : update_check_result_(UpdateEngineClient::UPDATE_RESULT_SUCCESS),
      can_rollback_stub_result_(false),
      reboot_after_update_call_count_(0),
      request_update_check_call_count_(0),
      rollback_call_count_(0),
      can_rollback_call_count_(0) {}

FakeUpdateEngineClient::~FakeUpdateEngineClient() {
}

void FakeUpdateEngineClient::Init(dbus::Bus* bus) {
}

void FakeUpdateEngineClient::AddObserver(Observer* observer) {
  observers_.AddObserver(observer);
}

void FakeUpdateEngineClient::RemoveObserver(Observer* observer) {
  observers_.RemoveObserver(observer);
}

bool FakeUpdateEngineClient::HasObserver(const Observer* observer) const {
  return observers_.HasObserver(observer);
}

void FakeUpdateEngineClient::RequestUpdateCheck(
    const UpdateCheckCallback& callback) {
  request_update_check_call_count_++;
  callback.Run(update_check_result_);
}

void FakeUpdateEngineClient::Rollback() {
  rollback_call_count_++;
}

void FakeUpdateEngineClient::CanRollbackCheck(
    const RollbackCheckCallback& callback) {
  can_rollback_call_count_++;
  callback.Run(can_rollback_stub_result_);
}

void FakeUpdateEngineClient::RebootAfterUpdate() {
  reboot_after_update_call_count_++;
}

UpdateEngineClient::Status FakeUpdateEngineClient::GetLastStatus() {
  if (status_queue_.empty())
    return default_status_;

  UpdateEngineClient::Status last_status = status_queue_.front();
  status_queue_.pop();
  return last_status;
}

void FakeUpdateEngineClient::NotifyObserversThatStatusChanged(
    const UpdateEngineClient::Status& status) {
  for (auto& observer : observers_)
    observer.UpdateStatusChanged(status);
}

void FakeUpdateEngineClient::SetChannel(const std::string& target_channel,
                                        bool is_powerwash_allowed) {
}

void FakeUpdateEngineClient::GetChannel(bool get_current_channel,
                                        const GetChannelCallback& callback) {
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::Bind(callback, std::string()));
}

void FakeUpdateEngineClient::GetEolStatus(
    const GetEolStatusCallback& callback) {
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::Bind(callback, update_engine::EndOfLifeStatus::kSupported));
}

void FakeUpdateEngineClient::set_default_status(
    const UpdateEngineClient::Status& status) {
  default_status_ = status;
}

void FakeUpdateEngineClient::set_update_check_result(
    const UpdateEngineClient::UpdateCheckResult& result) {
  update_check_result_ = result;
}

}  // namespace chromeos
