// Copyright 2020 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 CAST_STREAMING_SENDER_SESSION_H_
#define CAST_STREAMING_SENDER_SESSION_H_

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "cast/common/public/message_port.h"
#include "cast/streaming/answer_messages.h"
#include "cast/streaming/capture_configs.h"
#include "cast/streaming/offer_messages.h"
#include "cast/streaming/sender.h"
#include "cast/streaming/sender_packet_router.h"
#include "cast/streaming/session_config.h"
#include "cast/streaming/session_messager.h"
#include "json/value.h"
#include "util/json/json_serialization.h"

namespace openscreen {
namespace cast {

namespace capture_recommendations {
struct Recommendations;
}

class Environment;
class Sender;

class SenderSession final {
 public:
  // Upon successful negotiation, a set of configured senders is constructed
  // for handling audio and video. Note that either sender may be null.
  struct ConfiguredSenders {
    // In practice, we may have 0, 1, or 2 senders configured, depending
    // on if the device supports audio and video, and if we were able to
    // successfully negotiate a sender configuration.

    // If the sender is audio- or video-only, either of the senders
    // may be nullptr. However, in the majority of cases they will be populated.
    Sender* audio_sender;
    AudioCaptureConfig audio_config;

    Sender* video_sender;
    VideoCaptureConfig video_config;
  };

  // The embedder should provide a client for handling the negotiation.
  // When the negotiation is complete, the OnMirroringNegotiated callback is
  // called.
  class Client {
   public:
    // Called when a new set of senders has been negotiated. This may be
    // called multiple times during a session, once for every time
    // NegotiateMirroring() is called on the SenderSession object. The
    // negotiation call also includes capture recommendations that can be used
    // by the sender to provide an optimal video stream for the receiver.
    virtual void OnMirroringNegotiated(
        const SenderSession* session,
        ConfiguredSenders senders,
        capture_recommendations::Recommendations capture_recommendations) = 0;

    // Called whenever an error occurs. Ends the ongoing session, and the caller
    // must call NegotiateMirroring() again if they wish to re-establish
    // streaming.
    virtual void OnError(const SenderSession* session, Error error) = 0;

   protected:
    virtual ~Client();
  };

  // The SenderSession assumes that the passed in client, environment, and
  // message port persist for at least the lifetime of the SenderSession. If
  // one of these classes needs to be reset, a new SenderSession should be
  // created.
  //
  // |message_source_id| and |message_destination_id| are the local and remote
  // ID, respectively, to use when sending or receiving control messages (e.g.,
  // OFFERs or ANSWERs) over the |message_port|. |message_port|'s SetClient()
  // method will be called.
  SenderSession(IPAddress remote_address,
                Client* const client,
                Environment* environment,
                MessagePort* message_port,
                std::string message_source_id,
                std::string message_destination_id);
  SenderSession(const SenderSession&) = delete;
  SenderSession(SenderSession&&) noexcept = delete;
  SenderSession& operator=(const SenderSession&) = delete;
  SenderSession& operator=(SenderSession&&) = delete;
  ~SenderSession();

  // Starts an OFFER/ANSWER exchange with the already configured receiver
  // over the message port. The caller should assume any configured senders
  // become invalid when calling this method.
  Error NegotiateMirroring(std::vector<AudioCaptureConfig> audio_configs,
                           std::vector<VideoCaptureConfig> video_configs);

  // Get the current network usage (in bits per second). This includes all
  // senders managed by this session, and is a best guess based on receiver
  // feedback. Embedders may use this information to throttle capture devices.
  int GetEstimatedNetworkBandwidth() const;

 private:
  // We store the current negotiation, so that when we get an answer from the
  // receiver we can line up the selected streams with the original
  // configuration.
  struct Negotiation {
    Offer offer;

    std::vector<AudioCaptureConfig> audio_configs;
    std::vector<VideoCaptureConfig> video_configs;
  };

  // Specific message type handler methods.
  void OnAnswer(ReceiverMessage message);

  // Used by SpawnSenders to generate a sender for a specific stream.
  std::unique_ptr<Sender> CreateSender(Ssrc receiver_ssrc,
                                       const Stream& stream,
                                       RtpPayloadType type);

  // Helper methods for spawning specific senders from the Answer message.
  void SpawnAudioSender(ConfiguredSenders* senders,
                        Ssrc receiver_ssrc,
                        int send_index,
                        int config_index);
  void SpawnVideoSender(ConfiguredSenders* senders,
                        Ssrc receiver_ssrc,
                        int send_index,
                        int config_index);

  // Spawn a set of configured senders from the currently stored negotiation.
  ConfiguredSenders SpawnSenders(const Answer& answer);

  // The remote address of the receiver we are communicating with. Used
  // for both TLS and UDP traffic.
  const IPAddress remote_address_;

  // The embedder is expected to provide us a client for notifications about
  // negotiations and errors, a valid cast environment, and a messaging
  // port for communicating to the Receiver over TLS.
  Client* const client_;
  Environment* const environment_;
  SenderSessionMessager messager_;

  // The packet router used for messaging across all senders.
  SenderPacketRouter packet_router_;

  // Each negotiation has its own sequence number, and the receiver replies
  // with the same sequence number that we send. Each message to the receiver
  // advances our current sequence number.
  int current_sequence_number_ = 0;

  // The current negotiation. If present, we are expected an ANSWER from
  // the receiver. If not present, any provided ANSWERS are rejected.
  std::unique_ptr<Negotiation> current_negotiation_;

  // If the negotiation has succeeded, we store the current audio and video
  // senders used for this session. Either or both may be nullptr.
  std::unique_ptr<Sender> current_audio_sender_;
  std::unique_ptr<Sender> current_video_sender_;
};  // namespace cast

}  // namespace cast
}  // namespace openscreen

#endif  // CAST_STREAMING_SENDER_SESSION_H_
