// 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.

#ifndef DBUS_OBJECT_PROXY_H_
#define DBUS_OBJECT_PROXY_H_

#include <dbus/dbus.h>

#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/string_piece.h"
#include "base/time/time.h"
#include "dbus/dbus_export.h"
#include "dbus/object_path.h"

namespace base {
class TaskRunner;
}  // namespace base

namespace dbus {

class Bus;
class ErrorResponse;
class MethodCall;
class Response;
class ScopedDBusError;
class Signal;

// ObjectProxy is used to communicate with remote objects, mainly for
// calling methods of these objects.
//
// ObjectProxy is a ref counted object, to ensure that |this| of the
// object is alive when callbacks referencing |this| are called; the
// bus always holds at least one of those references so object proxies
// always last as long as the bus that created them.
class CHROME_DBUS_EXPORT ObjectProxy
    : public base::RefCountedThreadSafe<ObjectProxy> {
 public:
  // Client code should use Bus::GetObjectProxy() or
  // Bus::GetObjectProxyWithOptions() instead of this constructor.
  ObjectProxy(Bus* bus,
              const std::string& service_name,
              const ObjectPath& object_path,
              int options);

  // Options to be OR-ed together when calling Bus::GetObjectProxyWithOptions().
  // Set the IGNORE_SERVICE_UNKNOWN_ERRORS option to silence logging of
  // org.freedesktop.DBus.Error.ServiceUnknown errors and
  // org.freedesktop.DBus.Error.ObjectUnknown errors.
  enum Options {
    DEFAULT_OPTIONS = 0,
    IGNORE_SERVICE_UNKNOWN_ERRORS = 1 << 0
  };

  // Special timeout constants.
  //
  // The constants correspond to DBUS_TIMEOUT_USE_DEFAULT and
  // DBUS_TIMEOUT_INFINITE. Here we use literal numbers instead of these
  // macros as these aren't defined with D-Bus earlier than 1.4.12.
  enum {
    TIMEOUT_USE_DEFAULT = -1,
    TIMEOUT_INFINITE = 0x7fffffff,
  };

  // Called when an error response is returned or no response is returned.
  // Used for CallMethodWithErrorCallback().
  using ErrorCallback = base::OnceCallback<void(ErrorResponse*)>;

  // Called when the response is returned. Used for CallMethod().
  using ResponseCallback = base::OnceCallback<void(Response*)>;

  // Called when the response is returned or an error occurs. Used for
  // CallMethodWithErrorResponse().
  // Note that even in error case, ErrorResponse* may be nullptr.
  // E.g. out-of-memory error is found in libdbus, or the connection of
  // |bus_| is not yet established.
  using ResponseOrErrorCallback =
      base::OnceCallback<void(Response*, ErrorResponse*)>;

  // Called when a signal is received. Signal* is the incoming signal.
  using SignalCallback = base::Callback<void(Signal*)>;

  // Called when NameOwnerChanged signal is received.
  using NameOwnerChangedCallback =
      base::Callback<void(const std::string& old_owner,
                          const std::string& new_owner)>;

  // Called when the service becomes available.
  using WaitForServiceToBeAvailableCallback =
      base::OnceCallback<void(bool service_is_available)>;

  // Called when the object proxy is connected to the signal.
  // Parameters:
  // - the interface name.
  // - the signal name.
  // - whether it was successful or not.
  using OnConnectedCallback =
      base::OnceCallback<void(const std::string&, const std::string&, bool)>;

  // Calls the method of the remote object and blocks until the response
  // is returned. Returns NULL on error with the error details specified
  // in the |error| object.
  //
  // BLOCKING CALL.
  virtual std::unique_ptr<Response> CallMethodAndBlockWithErrorDetails(
      MethodCall* method_call,
      int timeout_ms,
      ScopedDBusError* error);

  // Calls the method of the remote object and blocks until the response
  // is returned. Returns NULL on error.
  //
  // BLOCKING CALL.
  virtual std::unique_ptr<Response> CallMethodAndBlock(MethodCall* method_call,
                                                       int timeout_ms);

  // Requests to call the method of the remote object.
  //
  // |callback| will be called in the origin thread, once the method call
  // is complete. As it's called in the origin thread, |callback| can
  // safely reference objects in the origin thread (i.e. UI thread in most
  // cases). If the caller is not interested in the response from the
  // method (i.e. calling a method that does not return a value),
  // EmptyResponseCallback() can be passed to the |callback| parameter.
  //
  // If the method call is successful, a pointer to Response object will
  // be passed to the callback. If unsuccessful, nullptr will be passed to
  // the callback.
  //
  // Must be called in the origin thread.
  virtual void CallMethod(MethodCall* method_call,
                          int timeout_ms,
                          ResponseCallback callback);

  // Requests to call the method of the remote object.
  //
  // This is almost as same as CallMethod() defined above.
  // The difference is that, the |callback| can take ErrorResponse.
  // In case of error, ErrorResponse object is passed to the |callback|
  // if the remote object returned an error, or nullptr if a response was not
  // received at all (e.g., D-Bus connection is not established). In either
  // error case, Response* should be nullptr.
  virtual void CallMethodWithErrorResponse(MethodCall* method_call,
                                           int timeout_ms,
                                           ResponseOrErrorCallback callback);

  // DEPRECATED. Please use CallMethodWithErrorResponse() instead.
  // TODO(hidehiko): Remove this when migration is done.
  // Requests to call the method of the remote object.
  //
  // |callback| and |error_callback| will be called in the origin thread, once
  // the method call is complete. As it's called in the origin thread,
  // |callback| can safely reference objects in the origin thread (i.e.
  // UI thread in most cases). If the caller is not interested in the response
  // from the method (i.e. calling a method that does not return a value),
  // EmptyResponseCallback() can be passed to the |callback| parameter.
  //
  // If the method call is successful, |callback| will be invoked with a
  // Response object. If unsuccessful, |error_callback| will be invoked with an
  // ErrorResponse object (if the remote object returned an error) or nullptr
  // (if a response was not received at all).
  //
  // Must be called in the origin thread.
  virtual void CallMethodWithErrorCallback(MethodCall* method_call,
                                           int timeout_ms,
                                           ResponseCallback callback,
                                           ErrorCallback error_callback);

  // Requests to connect to the signal from the remote object.
  //
  // |signal_callback| will be called in the origin thread, when the
  // signal is received from the remote object. As it's called in the
  // origin thread, |signal_callback| can safely reference objects in the
  // origin thread (i.e. UI thread in most cases).
  //
  // |on_connected_callback| is called when the object proxy is connected
  // to the signal, or failed to be connected, in the origin thread.
  //
  // If a SignalCallback has already been registered for the given
  // |interface_name| and |signal_name|, |signal_callback| will be
  // added to the list of callbacks for |interface_name| and
  // |signal_name|.
  //
  // Must be called in the origin thread.
  virtual void ConnectToSignal(const std::string& interface_name,
                               const std::string& signal_name,
                               SignalCallback signal_callback,
                               OnConnectedCallback on_connected_callback);

  // Sets a callback for "NameOwnerChanged" signal. The callback is called on
  // the origin thread when D-Bus system sends "NameOwnerChanged" for the name
  // represented by |service_name_|.
  virtual void SetNameOwnerChangedCallback(NameOwnerChangedCallback callback);

  // Registers |callback| to run when the service becomes available. If the
  // service is already available, or if connecting to the name-owner-changed
  // signal fails, |callback| will be run once asynchronously. Otherwise,
  // |callback| will be run once in the future after the service becomes
  // available.
  virtual void WaitForServiceToBeAvailable(
      WaitForServiceToBeAvailableCallback callback);

  // Detaches from the remote object. The Bus object will take care of
  // detaching so you don't have to do this manually.
  //
  // BLOCKING CALL.
  virtual void Detach();

  const ObjectPath& object_path() const { return object_path_; }

  // Returns an empty callback that does nothing. Can be used for
  // CallMethod().
  static ResponseCallback EmptyResponseCallback();

 protected:
  // This is protected, so we can define sub classes.
  virtual ~ObjectProxy();

 private:
  friend class base::RefCountedThreadSafe<ObjectProxy>;

  // Callback passed to CallMethod and its family should be deleted on the
  // origin thread in any cases. This class manages the work.
  class ReplyCallbackHolder {
   public:
    // Designed to be created on the origin thread.
    // Both |origin_task_runner| and |callback| must not be null.
    ReplyCallbackHolder(scoped_refptr<base::TaskRunner> origin_task_runner,
                        ResponseOrErrorCallback callback);

    // This is movable to be bound to an OnceCallback.
    ReplyCallbackHolder(ReplyCallbackHolder&& other);

    // |callback_| needs to be destroyed on the origin thread.
    // If this is not destroyed on non-origin thread, it PostTask()s the
    // callback to the origin thread for destroying.
    ~ReplyCallbackHolder();

    // Returns |callback_| with releasing its ownership.
    // This must be called on the origin thread.
    ResponseOrErrorCallback ReleaseCallback();

   private:
    scoped_refptr<base::TaskRunner> origin_task_runner_;
    ResponseOrErrorCallback callback_;
    DISALLOW_COPY_AND_ASSIGN(ReplyCallbackHolder);
  };

  // Starts the async method call. This is a helper function to implement
  // CallMethod().
  void StartAsyncMethodCall(int timeout_ms,
                            DBusMessage* request_message,
                            ReplyCallbackHolder callback_holder,
                            base::TimeTicks start_time);

  // Called when the pending call is complete.
  void OnPendingCallIsComplete(ReplyCallbackHolder callback_holder,
                               base::TimeTicks start_time,
                               DBusPendingCall* pending_call);

  // Runs the ResponseOrErrorCallback with the given response object.
  void RunResponseOrErrorCallback(ReplyCallbackHolder callback_holderk,
                                  base::TimeTicks start_time,
                                  Response* response,
                                  ErrorResponse* error_response);

  // Connects to NameOwnerChanged signal.
  bool ConnectToNameOwnerChangedSignal();

  // Helper function for ConnectToSignal().
  bool ConnectToSignalInternal(const std::string& interface_name,
                               const std::string& signal_name,
                               SignalCallback signal_callback);

  // Helper function for WaitForServiceToBeAvailable().
  void WaitForServiceToBeAvailableInternal();

  // Handles the incoming request messages and dispatches to the signal
  // callbacks.
  DBusHandlerResult HandleMessage(DBusConnection* connection,
                                  DBusMessage* raw_message);

  // Runs the method. Helper function for HandleMessage().
  void RunMethod(base::TimeTicks start_time,
                 std::vector<SignalCallback> signal_callbacks,
                 Signal* signal);

  // Redirects the function call to HandleMessage().
  static DBusHandlerResult HandleMessageThunk(DBusConnection* connection,
                                              DBusMessage* raw_message,
                                              void* user_data);

  // Helper method for logging response errors appropriately.
  void LogMethodCallFailure(const base::StringPiece& interface_name,
                            const base::StringPiece& method_name,
                            const base::StringPiece& error_name,
                            const base::StringPiece& error_message) const;

  // Used as ResponseOrErrorCallback by CallMethod().
  // Logs error message, and drops |error_response| from the arguments to pass
  // |response_callback|.
  void OnCallMethod(const std::string& interface_name,
                    const std::string& method_name,
                    ResponseCallback response_callback,
                    Response* response,
                    ErrorResponse* error_response);

  // Adds the match rule to the bus and associate the callback with the signal.
  bool AddMatchRuleWithCallback(const std::string& match_rule,
                                const std::string& absolute_signal_name,
                                SignalCallback signal_callback);

  // Adds the match rule to the bus so that HandleMessage can see the signal.
  bool AddMatchRuleWithoutCallback(const std::string& match_rule,
                                   const std::string& absolute_signal_name);

  // Calls D-Bus's GetNameOwner method synchronously to update
  // |service_name_owner_| with the current owner of |service_name_|.
  //
  // BLOCKING CALL.
  void UpdateNameOwnerAndBlock();

  // Handles NameOwnerChanged signal from D-Bus's special message bus.
  DBusHandlerResult HandleNameOwnerChanged(
      std::unique_ptr<dbus::Signal> signal);

  // Runs |name_owner_changed_callback_|.
  void RunNameOwnerChangedCallback(const std::string& old_owner,
                                   const std::string& new_owner);

  // Runs |wait_for_service_to_be_available_callbacks_|.
  void RunWaitForServiceToBeAvailableCallbacks(bool service_is_available);

  scoped_refptr<Bus> bus_;
  std::string service_name_;
  ObjectPath object_path_;

  // The method table where keys are absolute signal names (i.e. interface
  // name + signal name), and values are lists of the corresponding callbacks.
  using MethodTable = std::map<std::string, std::vector<SignalCallback>>;
  MethodTable method_table_;

  // The callback called when NameOwnerChanged signal is received.
  NameOwnerChangedCallback name_owner_changed_callback_;

  // Called when the service becomes available.
  std::vector<WaitForServiceToBeAvailableCallback>
      wait_for_service_to_be_available_callbacks_;

  std::set<std::string> match_rules_;

  const bool ignore_service_unknown_errors_;

  // Known name owner of the well-known bus name represented by |service_name_|.
  std::string service_name_owner_;

  std::set<DBusPendingCall*> pending_calls_;

  DISALLOW_COPY_AND_ASSIGN(ObjectProxy);
};

}  // namespace dbus

#endif  // DBUS_OBJECT_PROXY_H_
