/*
 * 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 ssrc) = 0;

  // Triggered when the remote SessionDescription has a new video track.
  virtual void OnAddRemoteVideoTrack(MediaStreamInterface* stream,
                                     VideoTrackInterface* video_track,
                                     uint32 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 ssrc) = 0;

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

  // Triggered when the local SessionDescription has removed an audio track.
  virtual void OnRemoveLocalAudioTrack(MediaStreamInterface* stream,
                                       AudioTrackInterface* audio_track,
                                       uint32 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 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 ssrc)
        : stream_label(stream_label),
          track_id(track_id),
          ssrc(ssrc) {
    }
    std::string stream_label;
    std::string track_id;
    uint32 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 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 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 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 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_
