// Copyright 2017 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 <utility>
#include <vector>

#include <base/logging.h>
#include <brillo/errors/error.h>

#include "chaps/dbus/dbus_proxy_wrapper.h"
#include "chaps/isolate.h"

namespace {

// Timeout of dbus proxy construction.
constexpr base::TimeDelta kConstructProxyTimeout =
    base::TimeDelta::FromMinutes(5);

void OnServiceAvailable(chaps::OnObjectProxyConstructedCallback callback,
                        chaps::ScopedBus bus,
                        scoped_refptr<dbus::ObjectProxy> proxy,
                        bool service_is_available) {
  if (!service_is_available) {
    LOG(ERROR) << "Failed to wait for chaps service to become available";
    callback.Run(false, chaps::ScopedBus(), nullptr);
    return;
  }

  // Call GetSlotList to perform stage 2 initialization of chapsd if it
  // hasn't already done so.
  brillo::ErrorPtr error;
  brillo::SecureBlob default_isolate_credential_blob =
      chaps::IsolateCredentialManager::GetDefaultIsolateCredential();

  std::vector<uint8_t> default_isolate_credential(
      default_isolate_credential_blob.begin(),
      default_isolate_credential_blob.end());

  if (!brillo::dbus_utils::CallMethodAndBlockWithTimeout(
          chaps::DBusProxyWrapper::kDBusTimeoutMs, proxy.get(),
          chaps::kChapsInterface, chaps::kGetSlotListMethod, &error,
          default_isolate_credential, false)) {
    LOG(ERROR) << "Chaps service is up but unresponsive: "
               << error->GetMessage();
    callback.Run(false, chaps::ScopedBus(), nullptr);
    return;
  }

  callback.Run(true, std::move(bus), proxy);
}

void CreateObjectProxyOnTaskRunner(
    const chaps::OnObjectProxyConstructedCallback& callback) {
  dbus::Bus::Options options;
  options.bus_type = dbus::Bus::SYSTEM;
  chaps::ScopedBus bus(options);

  auto proxy = bus->GetObjectProxy(chaps::kChapsServiceName,
                                   dbus::ObjectPath(chaps::kChapsServicePath));
  if (!proxy) {
    callback.Run(false, chaps::ScopedBus(), nullptr);
    return;
  }

  proxy->WaitForServiceToBeAvailable(base::Bind(&OnServiceAvailable, callback,
                                                base::Passed(std::move(bus)),
                                                base::WrapRefCounted(proxy)));
}

}  // namespace

namespace chaps {

ProxyWrapperConstructionTask::ProxyWrapperConstructionTask()
    : construction_callback_(base::Bind(&CreateObjectProxyOnTaskRunner)),
      completion_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                        base::WaitableEvent::InitialState::NOT_SIGNALED) {}

scoped_refptr<DBusProxyWrapper>
ProxyWrapperConstructionTask::ConstructProxyWrapper(
    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
  // This task will call the SetObjectProxyCallback with the results
  // of the construction attempt.
  task_runner->PostTask(
      FROM_HERE,
      base::Bind(
          construction_callback_,
          base::Bind(&ProxyWrapperConstructionTask::SetObjectProxyCallback,
                     this)));

  // If we wait too long for the chapsd service to become available,
  // cancel construction.
  if (!completion_event_.TimedWait(kConstructProxyTimeout)) {
    LOG(ERROR) << "Chaps service is not available";
    return nullptr;
  }

  // |completion_event_| was signaled, try constructing the proxy.
  if (!success_)
    return nullptr;

  return scoped_refptr<DBusProxyWrapper>(
      new DBusProxyWrapper(task_runner, std::move(bus_), object_proxy_));
}

void ProxyWrapperConstructionTask::SetObjectProxyCallback(
    bool success,
    ScopedBus bus,
    scoped_refptr<dbus::ObjectProxy> object_proxy) {
  success_ = success;
  bus_ = std::move(bus);
  object_proxy_ = object_proxy;
  completion_event_.Signal();
}

}  // namespace chaps
