// 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 "dbus/exported_object.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_path.h"
#include "dbus/scoped_dbus_error.h"

namespace dbus {

namespace {

// Used for success ratio histograms. 1 for success, 0 for failure.
const int kSuccessRatioHistogramMaxValue = 2;

// Gets the absolute method name by concatenating the interface name and
// the method name. Used for building keys for method_table_ in
// ExportedObject.
std::string GetAbsoluteMethodName(
    const std::string& interface_name,
    const std::string& method_name) {
  return interface_name + "." + method_name;
}

}  // namespace

ExportedObject::ExportedObject(Bus* bus,
                               const ObjectPath& object_path)
    : bus_(bus),
      object_path_(object_path),
      object_is_registered_(false) {
}

ExportedObject::~ExportedObject() {
  DCHECK(!object_is_registered_);
}

bool ExportedObject::ExportMethodAndBlock(
    const std::string& interface_name,
    const std::string& method_name,
    MethodCallCallback method_call_callback) {
  bus_->AssertOnDBusThread();

  // Check if the method is already exported.
  const std::string absolute_method_name =
      GetAbsoluteMethodName(interface_name, method_name);
  if (method_table_.find(absolute_method_name) != method_table_.end()) {
    LOG(ERROR) << absolute_method_name << " is already exported";
    return false;
  }

  if (!bus_->Connect())
    return false;
  if (!bus_->SetUpAsyncOperations())
    return false;
  if (!Register())
    return false;

  // Add the method callback to the method table.
  method_table_[absolute_method_name] = method_call_callback;

  return true;
}

void ExportedObject::ExportMethod(const std::string& interface_name,
                                  const std::string& method_name,
                                  MethodCallCallback method_call_callback,
                                  OnExportedCallback on_exported_calback) {
  bus_->AssertOnOriginThread();

  base::Closure task = base::Bind(&ExportedObject::ExportMethodInternal,
                                  this,
                                  interface_name,
                                  method_name,
                                  method_call_callback,
                                  on_exported_calback);
  bus_->PostTaskToDBusThread(FROM_HERE, task);
}

void ExportedObject::SendSignal(Signal* signal) {
  // For signals, the object path should be set to the path to the sender
  // object, which is this exported object here.
  CHECK(signal->SetPath(object_path_));

  // Increment the reference count so we can safely reference the
  // underlying signal message until the signal sending is complete. This
  // will be unref'ed in SendSignalInternal().
  DBusMessage* signal_message = signal->raw_message();
  dbus_message_ref(signal_message);

  const base::TimeTicks start_time = base::TimeTicks::Now();
  bus_->PostTaskToDBusThread(FROM_HERE,
                             base::Bind(&ExportedObject::SendSignalInternal,
                                        this,
                                        start_time,
                                        signal_message));
}

void ExportedObject::Unregister() {
  bus_->AssertOnDBusThread();

  if (!object_is_registered_)
    return;

  bus_->UnregisterObjectPath(object_path_);
  object_is_registered_ = false;
}

void ExportedObject::ExportMethodInternal(
    const std::string& interface_name,
    const std::string& method_name,
    MethodCallCallback method_call_callback,
    OnExportedCallback on_exported_calback) {
  bus_->AssertOnDBusThread();

  const bool success = ExportMethodAndBlock(interface_name,
                                            method_name,
                                            method_call_callback);
  bus_->PostTaskToOriginThread(FROM_HERE,
                               base::Bind(&ExportedObject::OnExported,
                                          this,
                                          on_exported_calback,
                                          interface_name,
                                          method_name,
                                          success));
}

void ExportedObject::OnExported(OnExportedCallback on_exported_callback,
                                const std::string& interface_name,
                                const std::string& method_name,
                                bool success) {
  bus_->AssertOnOriginThread();

  on_exported_callback.Run(interface_name, method_name, success);
}

void ExportedObject::SendSignalInternal(base::TimeTicks start_time,
                                        DBusMessage* signal_message) {
  uint32 serial = 0;
  bus_->Send(signal_message, &serial);
  dbus_message_unref(signal_message);
  // Record time spent to send the the signal. This is not accurate as the
  // signal will actually be sent from the next run of the message loop,
  // but we can at least tell the number of signals sent.
  UMA_HISTOGRAM_TIMES("DBus.SignalSendTime",
                      base::TimeTicks::Now() - start_time);
}

bool ExportedObject::Register() {
  bus_->AssertOnDBusThread();

  if (object_is_registered_)
    return true;

  ScopedDBusError error;

  DBusObjectPathVTable vtable = {};
  vtable.message_function = &ExportedObject::HandleMessageThunk;
  vtable.unregister_function = &ExportedObject::OnUnregisteredThunk;
  const bool success = bus_->TryRegisterObjectPath(object_path_,
                                                   &vtable,
                                                   this,
                                                   error.get());
  if (!success) {
    LOG(ERROR) << "Failed to register the object: " << object_path_.value()
               << ": " << (error.is_set() ? error.message() : "");
    return false;
  }

  object_is_registered_ = true;
  return true;
}

DBusHandlerResult ExportedObject::HandleMessage(
    DBusConnection* connection,
    DBusMessage* raw_message) {
  bus_->AssertOnDBusThread();
  DCHECK_EQ(DBUS_MESSAGE_TYPE_METHOD_CALL, dbus_message_get_type(raw_message));

  // raw_message will be unrefed on exit of the function. Increment the
  // reference so we can use it in MethodCall.
  dbus_message_ref(raw_message);
  scoped_ptr<MethodCall> method_call(
      MethodCall::FromRawMessage(raw_message));
  const std::string interface = method_call->GetInterface();
  const std::string member = method_call->GetMember();

  if (interface.empty()) {
    // We don't support method calls without interface.
    LOG(WARNING) << "Interface is missing: " << method_call->ToString();
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  }

  // Check if we know about the method.
  const std::string absolute_method_name = GetAbsoluteMethodName(
      interface, member);
  MethodTable::const_iterator iter = method_table_.find(absolute_method_name);
  if (iter == method_table_.end()) {
    // Don't know about the method.
    LOG(WARNING) << "Unknown method: " << method_call->ToString();
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  }

  const base::TimeTicks start_time = base::TimeTicks::Now();
  if (bus_->HasDBusThread()) {
    // Post a task to run the method in the origin thread.
    bus_->PostTaskToOriginThread(FROM_HERE,
                                 base::Bind(&ExportedObject::RunMethod,
                                            this,
                                            iter->second,
                                            base::Passed(&method_call),
                                            start_time));
  } else {
    // If the D-Bus thread is not used, just call the method directly.
    MethodCall* method = method_call.get();
    iter->second.Run(method,
                     base::Bind(&ExportedObject::SendResponse,
                                this,
                                start_time,
                                base::Passed(&method_call)));
  }

  // It's valid to say HANDLED here, and send a method response at a later
  // time from OnMethodCompleted() asynchronously.
  return DBUS_HANDLER_RESULT_HANDLED;
}

void ExportedObject::RunMethod(MethodCallCallback method_call_callback,
                               scoped_ptr<MethodCall> method_call,
                               base::TimeTicks start_time) {
  bus_->AssertOnOriginThread();
  MethodCall* method = method_call.get();
  method_call_callback.Run(method,
                           base::Bind(&ExportedObject::SendResponse,
                                      this,
                                      start_time,
                                      base::Passed(&method_call)));
}

void ExportedObject::SendResponse(base::TimeTicks start_time,
                                  scoped_ptr<MethodCall> method_call,
                                  scoped_ptr<Response> response) {
  DCHECK(method_call);
  if (bus_->HasDBusThread()) {
    bus_->PostTaskToDBusThread(FROM_HERE,
                               base::Bind(&ExportedObject::OnMethodCompleted,
                                          this,
                                          base::Passed(&method_call),
                                          base::Passed(&response),
                                          start_time));
  } else {
    OnMethodCompleted(method_call.Pass(), response.Pass(), start_time);
  }
}

void ExportedObject::OnMethodCompleted(scoped_ptr<MethodCall> method_call,
                                       scoped_ptr<Response> response,
                                       base::TimeTicks start_time) {
  bus_->AssertOnDBusThread();

  // Record if the method call is successful, or not. 1 if successful.
  UMA_HISTOGRAM_ENUMERATION("DBus.ExportedMethodHandleSuccess",
                            response ? 1 : 0,
                            kSuccessRatioHistogramMaxValue);

  // Check if the bus is still connected. If the method takes long to
  // complete, the bus may be shut down meanwhile.
  if (!bus_->is_connected())
    return;

  if (!response) {
    // Something bad happened in the method call.
    scoped_ptr<ErrorResponse> error_response(
        ErrorResponse::FromMethodCall(
            method_call.get(),
            DBUS_ERROR_FAILED,
            "error occurred in " + method_call->GetMember()));
    bus_->Send(error_response->raw_message(), NULL);
    return;
  }

  // The method call was successful.
  bus_->Send(response->raw_message(), NULL);

  // Record time spent to handle the the method call. Don't include failures.
  UMA_HISTOGRAM_TIMES("DBus.ExportedMethodHandleTime",
                      base::TimeTicks::Now() - start_time);
}

void ExportedObject::OnUnregistered(DBusConnection* connection) {
}

DBusHandlerResult ExportedObject::HandleMessageThunk(
    DBusConnection* connection,
    DBusMessage* raw_message,
    void* user_data) {
  ExportedObject* self = reinterpret_cast<ExportedObject*>(user_data);
  return self->HandleMessage(connection, raw_message);
}

void ExportedObject::OnUnregisteredThunk(DBusConnection *connection,
                                         void* user_data) {
  ExportedObject* self = reinterpret_cast<ExportedObject*>(user_data);
  return self->OnUnregistered(connection);
}

}  // namespace dbus
