// Copyright 2018 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 COMPONENTS_CAST_CHANNEL_CAST_MESSAGE_HANDLER_H_
#define COMPONENTS_CAST_CHANNEL_CAST_MESSAGE_HANDLER_H_

#include "base/callback_list.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/time/tick_clock.h"
#include "base/token.h"
#include "base/values.h"
#include "components/cast_channel/cast_message_util.h"
#include "components/cast_channel/cast_socket.h"

namespace service_manager {
class Connector;
}

namespace cast_channel {

class CastSocketService;

template <typename CallbackType>
struct PendingRequest {
 public:
  PendingRequest(int request_id,
                 CallbackType callback,
                 const base::TickClock* clock)
      : request_id(request_id),
        callback(std::move(callback)),
        timeout_timer(clock) {}

  virtual ~PendingRequest() = default;

  int request_id;
  CallbackType callback;
  base::OneShotTimer timeout_timer;
};

// |app_id|: ID of app the result is for.
// |result|: Availability result from the receiver.
using GetAppAvailabilityCallback =
    base::OnceCallback<void(const std::string& app_id,
                            GetAppAvailabilityResult result)>;

// Represents an app availability request to a Cast sink.
struct GetAppAvailabilityRequest
    : public PendingRequest<GetAppAvailabilityCallback> {
 public:
  GetAppAvailabilityRequest(int request_id,
                            GetAppAvailabilityCallback callback,
                            const base::TickClock* clock,
                            const std::string& app_id);
  ~GetAppAvailabilityRequest() override;

  // App ID of the request.
  std::string app_id;
};

// Represents an app launch request to a Cast sink.
using LaunchSessionCallback =
    base::OnceCallback<void(LaunchSessionResponse response)>;
using LaunchSessionRequest = PendingRequest<LaunchSessionCallback>;

// Represents an app stop request to a Cast sink.
// |success|: Whether the app was successfully stopped.
using StopSessionCallback = base::OnceCallback<void(bool success)>;
using StopSessionRequest = PendingRequest<StopSessionCallback>;

// Represents a virtual connection on a cast channel. A virtual connection is
// given by a source and destination ID pair, and must be created before
// messages can be sent. Virtual connections are managed by CastMessageHandler.
struct VirtualConnection {
  VirtualConnection(int channel_id,
                    const std::string& source_id,
                    const std::string& destination_id);
  ~VirtualConnection();

  bool operator<(const VirtualConnection& other) const;

  // ID of cast channel.
  int channel_id;

  // Source ID (e.g. sender-0).
  std::string source_id;

  // Destination ID (e.g. receiver-0).
  std::string destination_id;
};

struct InternalMessage {
  InternalMessage(CastMessageType type, base::Value message);
  ~InternalMessage();

  CastMessageType type;
  base::Value message;
};

// Handles messages that are sent between this browser instance and the Cast
// devices connected to it. This class also manages virtual connections (VCs)
// with each connected Cast device and ensures a proper VC exists before the
// message is sent. This makes the concept of VC transparent to the client.
// This class may be created on any sequence, but other methods (including
// destructor) must be run on the same sequence that CastSocketService runs on.
class CastMessageHandler : public CastSocket::Observer {
 public:
  class Observer {
   public:
    virtual ~Observer() = default;
    virtual void OnAppMessage(int channel_id, const CastMessage& message) {}
    virtual void OnInternalMessage(int channel_id,
                                   const InternalMessage& message) {}
  };

  // |connector|: Connector to be used for data_decoder service. The connector
  // must not be bound to any thread.
  // |data_decoder_batch_id|: Batch ID used for data_decoder service.
  CastMessageHandler(CastSocketService* socket_service,
                     std::unique_ptr<service_manager::Connector> connector,
                     const base::Token& data_decoder_batch_id,
                     const std::string& user_agent,
                     const std::string& browser_version,
                     const std::string& locale);
  ~CastMessageHandler() override;

  // Ensures a virtual connection exists for (|source_id|, |destination_id|) on
  // the device given by |channel_id|, sending a virtual connection request to
  // the device if necessary. Although a virtual connection is automatically
  // created when sending a message, a caller may decide to create it beforehand
  // in order to receive messages sooner.
  virtual void EnsureConnection(int channel_id,
                                const std::string& source_id,
                                const std::string& destination_id);

  // Sends an app availability for |app_id| to the device given by |socket|.
  // |callback| is always invoked asynchronously, and will be invoked when a
  // response is received, or if the request timed out. No-ops if there is
  // already a pending request with the same socket and app ID.
  virtual void RequestAppAvailability(CastSocket* socket,
                                      const std::string& app_id,
                                      GetAppAvailabilityCallback callback);

  // Sends a receiver status request to the socket given by |channel_id|.
  virtual void RequestReceiverStatus(int channel_id);

  // Sends a broadcast message containing |app_ids| and |request| to the socket
  // given by |channel_id|.
  virtual void SendBroadcastMessage(int channel_id,
                                    const std::vector<std::string>& app_ids,
                                    const BroadcastRequest& request);

  // Requests a session launch for |app_id| on the device given by |channel_id|.
  // |callback| will be invoked with the response or with a timed out result if
  // no response comes back before |launch_timeout|.
  virtual void LaunchSession(int channel_id,
                             const std::string& app_id,
                             base::TimeDelta launch_timeout,
                             LaunchSessionCallback callback);

  // Stops the session given by |session_id| on the device given by
  // |channel_id|. |callback| will be invoked with the result of the stop
  // request.
  virtual void StopSession(int channel_id,
                           const std::string& session_id,
                           StopSessionCallback callback);

  // Sends |message| to the device given by |channel_id|. The caller may use
  // this method to forward app messages from the SDK client to the device. It
  // is invalid to call this method with a message in one of the Cast internal
  // message namespaces.
  virtual void SendAppMessage(int channel_id, const CastMessage& message);

  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // CastSocket::Observer implementation.
  void OnError(const CastSocket& socket, ChannelError error_state) override;
  void OnMessage(const CastSocket& socket, const CastMessage& message) override;

  const std::string& sender_id() const { return sender_id_; }

 private:
  friend class CastMessageHandlerTest;

  // Set of PendingRequests for a CastSocket.
  class PendingRequests {
   public:
    PendingRequests();
    ~PendingRequests();

    bool AddAppAvailabilityRequest(
        std::unique_ptr<GetAppAvailabilityRequest> request);
    bool AddLaunchRequest(std::unique_ptr<LaunchSessionRequest> request,
                          base::TimeDelta timeout);
    bool AddStopRequest(std::unique_ptr<StopSessionRequest> request);
    void HandlePendingRequest(int request_id, const base::Value& response);

   private:
    // Invokes the pending callback associated with |request_id| with a timed
    // out result.
    void AppAvailabilityTimedOut(int request_id);
    void LaunchSessionTimedOut(int request_id);
    void StopSessionTimedOut(int request_id);

    // App availability requests pending responses, keyed by app ID.
    base::flat_map<std::string, std::unique_ptr<GetAppAvailabilityRequest>>
        pending_app_availability_requests_;
    std::unique_ptr<LaunchSessionRequest> pending_launch_session_request_;
    std::unique_ptr<StopSessionRequest> pending_stop_session_request_;
  };

  // Used internally to generate the next ID to use in a request type message.
  int NextRequestId() { return ++next_request_id_; }

  PendingRequests* GetOrCreatePendingRequests(int channel_id);

  // Sends |message| over |socket|. This also ensures the necessary virtual
  // connection exists before sending the message.
  void SendCastMessage(CastSocket* socket, const CastMessage& message);

  // Sends a virtual connection request to |socket| if the virtual connection
  // for (|source_id|, |destination_id|) does not yet exist.
  void DoEnsureConnection(CastSocket* socket,
                          const std::string& source_id,
                          const std::string& destination_id);

  // Callback for CastTransport::SendMessage.
  void OnMessageSent(int result);

  void HandleCastInternalMessage(int channel_id,
                                 const std::string& source_id,
                                 const std::string& destination_id,
                                 std::unique_ptr<base::Value> payload);

  // Set of pending requests keyed by socket ID.
  base::flat_map<int, std::unique_ptr<PendingRequests>> pending_requests_;

  // Source ID used for platform messages. The suffix is randomized to
  // distinguish it from other Cast senders on the same network.
  const std::string sender_id_;

  // Used for parsing JSON payload from receivers.
  std::unique_ptr<service_manager::Connector> connector_;
  const base::Token data_decoder_batch_id_;

  // User agent and browser version strings included in virtual connection
  // messages.
  const std::string user_agent_;
  const std::string browser_version_;

  // Locale string used for session launch requests.
  const std::string locale_;

  int next_request_id_ = 0;

  base::ObserverList<Observer>::Unchecked observers_;

  // Set of virtual connections opened to receivers.
  base::flat_set<VirtualConnection> virtual_connections_;

  CastSocketService* const socket_service_;

  // Non-owned pointer to TickClock used for request timeouts.
  const base::TickClock* const clock_;

  SEQUENCE_CHECKER(sequence_checker_);
  base::WeakPtrFactory<CastMessageHandler> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(CastMessageHandler);
};

}  // namespace cast_channel

#endif  // COMPONENTS_CAST_CHANNEL_CAST_MESSAGE_HANDLER_H_
