// 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::RepeatingCallback<void(Signal*)>;

  // Called when NameOwnerChanged signal is received.
  using NameOwnerChangedCallback =
      base::RepeatingCallback<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 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 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_; }

 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();

  // Tries to connect to NameOwnerChanged signal, ignores any error.
  void TryConnectToNameOwnerChangedSignal();

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