/*
 * libjingle
 * Copyright 2012 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef TALK_APP_WEBRTC_MEDIASTREAMSIGNALING_H_
#define TALK_APP_WEBRTC_MEDIASTREAMSIGNALING_H_

#include <map>
#include <string>
#include <vector>

#include "talk/app/webrtc/datachannel.h"
#include "talk/app/webrtc/mediastream.h"
#include "talk/app/webrtc/peerconnectioninterface.h"
#include "talk/app/webrtc/streamcollection.h"
#include "talk/session/media/mediasession.h"
#include "webrtc/base/scoped_ref_ptr.h"
#include "webrtc/base/sigslot.h"

namespace rtc {
class Thread;
}  // namespace rtc

namespace webrtc {

class RemoteMediaStreamFactory;

// A MediaStreamSignalingObserver is notified when events happen to
// MediaStreams, MediaStreamTracks or DataChannels associated with the observed
// MediaStreamSignaling object. The notifications identify the stream, track or
// channel.
class MediaStreamSignalingObserver {
 public:
  // Triggered when the remote SessionDescription has a new stream.
  virtual void OnAddRemoteStream(MediaStreamInterface* stream) = 0;

  // Triggered when the remote SessionDescription removes a stream.
  virtual void OnRemoveRemoteStream(MediaStreamInterface* stream) = 0;

  // Triggered when the remote SessionDescription has a new data channel.
  virtual void OnAddDataChannel(DataChannelInterface* data_channel) = 0;

  // Triggered when the remote SessionDescription has a new audio track.
  virtual void OnAddRemoteAudioTrack(MediaStreamInterface* stream,
                                     AudioTrackInterface* audio_track,
                                     uint32_t ssrc) = 0;

  // Triggered when the remote SessionDescription has a new video track.
  virtual void OnAddRemoteVideoTrack(MediaStreamInterface* stream,
                                     VideoTrackInterface* video_track,
                                     uint32_t ssrc) = 0;

  // Triggered when the remote SessionDescription has removed an audio track.
  virtual void OnRemoveRemoteAudioTrack(MediaStreamInterface* stream,
                                        AudioTrackInterface* audio_track)  = 0;

  // Triggered when the remote SessionDescription has removed a video track.
  virtual void OnRemoveRemoteVideoTrack(MediaStreamInterface* stream,
                                        VideoTrackInterface* video_track) = 0;

  // Triggered when the local SessionDescription has a new audio track.
  virtual void OnAddLocalAudioTrack(MediaStreamInterface* stream,
                                    AudioTrackInterface* audio_track,
                                    uint32_t ssrc) = 0;

  // Triggered when the local SessionDescription has a new video track.
  virtual void OnAddLocalVideoTrack(MediaStreamInterface* stream,
                                    VideoTrackInterface* video_track,
                                    uint32_t ssrc) = 0;

  // Triggered when the local SessionDescription has removed an audio track.
  virtual void OnRemoveLocalAudioTrack(MediaStreamInterface* stream,
                                       AudioTrackInterface* audio_track,
                                       uint32_t ssrc) = 0;

  // Triggered when the local SessionDescription has removed a video track.
  virtual void OnRemoveLocalVideoTrack(MediaStreamInterface* stream,
                                       VideoTrackInterface* video_track) = 0;

  // Triggered when RemoveLocalStream is called. |stream| is no longer used
  // when negotiating and all tracks in |stream| should stop providing data to
  // this PeerConnection. This doesn't mean that the local session description
  // has changed and OnRemoveLocalAudioTrack and OnRemoveLocalVideoTrack is not
  // called for each individual track.
  virtual void OnRemoveLocalStream(MediaStreamInterface* stream) = 0;

 protected:
  ~MediaStreamSignalingObserver() {}
};

// MediaStreamSignaling works as a glue between MediaStreams and a cricket
// classes for SessionDescriptions.
// It is used for creating cricket::MediaSessionOptions given the local
// MediaStreams and data channels.
//
// It is responsible for creating remote MediaStreams given a remote
// SessionDescription and creating cricket::MediaSessionOptions given
// local MediaStreams.
//
// To signal that a DataChannel should be established:
// 1. Call AddDataChannel with the new DataChannel. Next time
//    GetMediaSessionOptions will include the description of the DataChannel.
// 2. When a local session description is set, call UpdateLocalStreams with the
//    session description. This will set the SSRC used for sending data on
//    this DataChannel.
// 3. When remote session description is set, call UpdateRemoteStream with the
//    session description. If the DataChannel label and a SSRC is included in
//    the description, the DataChannel is updated with SSRC that will be used
//    for receiving data.
// 4. When both the local and remote SSRC of a DataChannel is set the state of
//    the DataChannel change to kOpen.
//
// To setup a DataChannel initialized by the remote end.
// 1. When remote session description is set, call UpdateRemoteStream with the
//    session description. If a label and a SSRC of a new DataChannel is found
//    MediaStreamSignalingObserver::OnAddDataChannel with the label and SSRC is
//    triggered.
// 2. Create a DataChannel instance with the label and set the remote SSRC.
// 3. Call AddDataChannel with this new DataChannel.  GetMediaSessionOptions
//    will include the description of the DataChannel.
// 4. Create a local session description and call UpdateLocalStreams. This will
//    set the local SSRC used by the DataChannel.
// 5. When both the local and remote SSRC of a DataChannel is set the state of
//    the DataChannel change to kOpen.
//
// To close a DataChannel:
// 1. Call DataChannel::Close. This will change the state of the DataChannel to
//    kClosing. GetMediaSessionOptions will not
//    include the description of the DataChannel.
// 2. When a local session description is set, call UpdateLocalStreams with the
//    session description. The description will no longer contain the
//    DataChannel label or SSRC.
// 3. When remote session description is set, call UpdateRemoteStream with the
//    session description. The description will no longer contain the
//    DataChannel label or SSRC. The DataChannel SSRC is updated with SSRC=0.
//    The DataChannel change state to kClosed.

class MediaStreamSignaling : public sigslot::has_slots<> {
 public:
  typedef std::map<std::string, rtc::scoped_refptr<DataChannel> >
      RtpDataChannels;
  typedef std::vector<rtc::scoped_refptr<DataChannel>> SctpDataChannels;

  MediaStreamSignaling(rtc::Thread* signaling_thread,
                       MediaStreamSignalingObserver* stream_observer,
                       cricket::ChannelManager* channel_manager);
  virtual ~MediaStreamSignaling();

  // Notify all referenced objects that MediaStreamSignaling will be teared
  // down. This method must be called prior to the dtor.
  void TearDown();

  // Set a factory for creating data channels that are initiated by the remote
  // peer.
  void SetDataChannelFactory(DataChannelFactory* data_channel_factory) {
    data_channel_factory_ = data_channel_factory;
  }

  // Checks if |id| is available to be assigned to a new SCTP data channel.
  bool IsSctpSidAvailable(int sid) const;

  // Gets the first available SCTP id that is not assigned to any existing
  // data channels.
  bool AllocateSctpSid(rtc::SSLRole role, int* sid);

  // Adds |local_stream| to the collection of known MediaStreams that will be
  // offered in a SessionDescription.
  bool AddLocalStream(MediaStreamInterface* local_stream);

  // Removes |local_stream| from the collection of known MediaStreams that will
  // be offered in a SessionDescription.
  void RemoveLocalStream(MediaStreamInterface* local_stream);

  // Checks if any data channel has been added.
  bool HasDataChannels() const;
  // Adds |data_channel| to the collection of DataChannels that will be
  // be offered in a SessionDescription.
  bool AddDataChannel(DataChannel* data_channel);
  // After we receive an OPEN message, create a data channel and add it.
  bool AddDataChannelFromOpenMessage(const cricket::ReceiveDataParams& params,
                                     const rtc::Buffer& payload);
  void RemoveSctpDataChannel(int sid);

  // Returns a MediaSessionOptions struct with options decided by |options|,
  // the local MediaStreams and DataChannels.
  virtual bool GetOptionsForOffer(
      const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
      cricket::MediaSessionOptions* session_options);

  // Returns a MediaSessionOptions struct with options decided by
  // |constraints|, the local MediaStreams and DataChannels.
  virtual bool GetOptionsForAnswer(
      const MediaConstraintsInterface* constraints,
      cricket::MediaSessionOptions* options);

  // Called when the remote session description has changed. The purpose is to
  // update remote MediaStreams and DataChannels with the current
  // session state.
  // If the remote SessionDescription contain information about a new remote
  // MediaStreams a new remote MediaStream is created and
  // MediaStreamSignalingObserver::OnAddStream is called.
  // If a remote MediaStream is missing from
  // the remote SessionDescription MediaStreamSignalingObserver::OnRemoveStream
  // is called.
  // If the SessionDescription contains information about a new DataChannel,
  // MediaStreamSignalingObserver::OnAddDataChannel is called with the
  // DataChannel.
  void OnRemoteDescriptionChanged(const SessionDescriptionInterface* desc);

  // Called when the local session description has changed. The purpose is to
  // update local and remote MediaStreams and DataChannels with the current
  // session state.
  // If |desc| indicates that the media type should be rejected, the method
  // ends the remote MediaStreamTracks.
  // It also updates local DataChannels with information about its local SSRC.
  void OnLocalDescriptionChanged(const SessionDescriptionInterface* desc);

  // Called when the audio channel closes.
  void OnAudioChannelClose();
  // Called when the video channel closes.
  void OnVideoChannelClose();
  // Called when the data channel closes.
  void OnDataChannelClose();

  // Returns all current known local MediaStreams.
  StreamCollectionInterface* local_streams() const { return local_streams_;}

  // Returns all current remote MediaStreams.
  StreamCollectionInterface* remote_streams() const {
    return remote_streams_.get();
  }
  void OnDataTransportCreatedForSctp();
  void OnDtlsRoleReadyForSctp(rtc::SSLRole role);
  void OnRemoteSctpDataChannelClosed(uint32_t sid);

  const SctpDataChannels& sctp_data_channels() const {
    return sctp_data_channels_;
  }

 private:
  struct RemotePeerInfo {
    RemotePeerInfo()
        : msid_supported(false),
          default_audio_track_needed(false),
          default_video_track_needed(false) {
    }
    // True if it has been discovered that the remote peer support MSID.
    bool msid_supported;
    // The remote peer indicates in the session description that audio will be
    // sent but no MSID is given.
    bool default_audio_track_needed;
    // The remote peer indicates in the session description that video will be
    // sent but no MSID is given.
    bool default_video_track_needed;

    bool IsDefaultMediaStreamNeeded() {
      return !msid_supported && (default_audio_track_needed ||
          default_video_track_needed);
    }
  };

  struct TrackInfo {
    TrackInfo() : ssrc(0) {}
    TrackInfo(const std::string& stream_label,
              const std::string track_id,
              uint32_t ssrc)
        : stream_label(stream_label), track_id(track_id), ssrc(ssrc) {}
    std::string stream_label;
    std::string track_id;
    uint32_t ssrc;
  };
  typedef std::vector<TrackInfo> TrackInfos;

  // Makes sure a MediaStream Track is created for each StreamParam in
  // |streams|. |media_type| is the type of the |streams| and can be either
  // audio or video.
  // If a new MediaStream is created it is added to |new_streams|.
  void UpdateRemoteStreamsList(
      const std::vector<cricket::StreamParams>& streams,
      cricket::MediaType media_type,
      StreamCollection* new_streams);

  // Triggered when a remote track has been seen for the first time in a remote
  // session description. It creates a remote MediaStreamTrackInterface
  // implementation and triggers MediaStreamSignaling::OnAddRemoteAudioTrack or
  // MediaStreamSignaling::OnAddRemoteVideoTrack.
  void OnRemoteTrackSeen(const std::string& stream_label,
                         const std::string& track_id,
                         uint32_t ssrc,
                         cricket::MediaType media_type);

  // Triggered when a remote track has been removed from a remote session
  // description. It removes the remote track with id |track_id| from a remote
  // MediaStream and triggers MediaStreamSignaling::OnRemoveRemoteAudioTrack or
  // MediaStreamSignaling::OnRemoveRemoteVideoTrack.
  void OnRemoteTrackRemoved(const std::string& stream_label,
                            const std::string& track_id,
                            cricket::MediaType media_type);

  // Set the MediaStreamTrackInterface::TrackState to |kEnded| on all remote
  // tracks of type |media_type|.
  void RejectRemoteTracks(cricket::MediaType media_type);

  // Finds remote MediaStreams without any tracks and removes them from
  // |remote_streams_| and notifies the observer that the MediaStream no longer
  // exist.
  void UpdateEndedRemoteMediaStreams();
  void MaybeCreateDefaultStream();
  TrackInfos* GetRemoteTracks(cricket::MediaType type);

  // Returns a map of currently negotiated LocalTrackInfo of type |type|.
  TrackInfos* GetLocalTracks(cricket::MediaType type);
  bool FindLocalTrack(const std::string& track_id, cricket::MediaType type);

  // Loops through the vector of |streams| and finds added and removed
  // StreamParams since last time this method was called.
  // For each new or removed StreamParam NotifyLocalTrackAdded or
  // NotifyLocalTrackRemoved in invoked.
  void UpdateLocalTracks(const std::vector<cricket::StreamParams>& streams,
                         cricket::MediaType media_type);

  // Triggered when a local track has been seen for the first time in a local
  // session description.
  // This method triggers MediaStreamSignaling::OnAddLocalAudioTrack or
  // MediaStreamSignaling::OnAddLocalVideoTrack if the rtp streams in the local
  // SessionDescription can be mapped to a MediaStreamTrack in a MediaStream in
  // |local_streams_|
  void OnLocalTrackSeen(const std::string& stream_label,
                        const std::string& track_id,
                        uint32_t ssrc,
                        cricket::MediaType media_type);

  // Triggered when a local track has been removed from a local session
  // description.
  // This method triggers MediaStreamSignaling::OnRemoveLocalAudioTrack or
  // MediaStreamSignaling::OnRemoveLocalVideoTrack if a stream has been removed
  // from the local SessionDescription and the stream can be mapped to a
  // MediaStreamTrack in a MediaStream in |local_streams_|.
  void OnLocalTrackRemoved(const std::string& stream_label,
                           const std::string& track_id,
                           uint32_t ssrc,
                           cricket::MediaType media_type);

  void UpdateLocalRtpDataChannels(const cricket::StreamParamsVec& streams);
  void UpdateRemoteRtpDataChannels(const cricket::StreamParamsVec& streams);
  void UpdateClosingDataChannels(
      const std::vector<std::string>& active_channels, bool is_local_update);
  void CreateRemoteDataChannel(const std::string& label, uint32_t remote_ssrc);

  const TrackInfo* FindTrackInfo(const TrackInfos& infos,
                                 const std::string& stream_label,
                                 const std::string track_id) const;

  // Returns the index of the specified SCTP DataChannel in sctp_data_channels_,
  // or -1 if not found.
  int FindDataChannelBySid(int sid) const;

  RemotePeerInfo remote_info_;
  rtc::Thread* signaling_thread_;
  DataChannelFactory* data_channel_factory_;
  MediaStreamSignalingObserver* stream_observer_;
  rtc::scoped_refptr<StreamCollection> local_streams_;
  rtc::scoped_refptr<StreamCollection> remote_streams_;
  rtc::scoped_ptr<RemoteMediaStreamFactory> remote_stream_factory_;

  TrackInfos remote_audio_tracks_;
  TrackInfos remote_video_tracks_;
  TrackInfos local_audio_tracks_;
  TrackInfos local_video_tracks_;

  int last_allocated_sctp_even_sid_;
  int last_allocated_sctp_odd_sid_;

  RtpDataChannels rtp_data_channels_;
  SctpDataChannels sctp_data_channels_;
};

}  // namespace webrtc

#endif  // TALK_APP_WEBRTC_MEDIASTREAMSIGNALING_H_
