/*
 *  Copyright 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "pc/media_stream_observer.h"

#include <functional>
#include <string>
#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "api/media_stream_interface.h"

namespace webrtc {

MediaStreamObserver::MediaStreamObserver(
    MediaStreamInterface* stream,
    std::function<void(AudioTrackInterface*, MediaStreamInterface*)>
        audio_track_added_callback,
    std::function<void(AudioTrackInterface*, MediaStreamInterface*)>
        audio_track_removed_callback,
    std::function<void(VideoTrackInterface*, MediaStreamInterface*)>
        video_track_added_callback,
    std::function<void(VideoTrackInterface*, MediaStreamInterface*)>
        video_track_removed_callback)
    : stream_(stream),
      cached_audio_tracks_(stream->GetAudioTracks()),
      cached_video_tracks_(stream->GetVideoTracks()),
      audio_track_added_callback_(std::move(audio_track_added_callback)),
      audio_track_removed_callback_(std::move(audio_track_removed_callback)),
      video_track_added_callback_(std::move(video_track_added_callback)),
      video_track_removed_callback_(std::move(video_track_removed_callback)) {
  stream_->RegisterObserver(this);
}

MediaStreamObserver::~MediaStreamObserver() {
  stream_->UnregisterObserver(this);
}

void MediaStreamObserver::OnChanged() {
  AudioTrackVector new_audio_tracks = stream_->GetAudioTracks();
  VideoTrackVector new_video_tracks = stream_->GetVideoTracks();

  // Find removed audio tracks.
  for (const auto& cached_track : cached_audio_tracks_) {
    if (absl::c_none_of(
            new_audio_tracks,
            [cached_track](const AudioTrackVector::value_type& new_track) {
              return new_track->id() == cached_track->id();
            })) {
      audio_track_removed_callback_(cached_track.get(), stream_.get());
    }
  }

  // Find added audio tracks.
  for (const auto& new_track : new_audio_tracks) {
    if (absl::c_none_of(
            cached_audio_tracks_,
            [new_track](const AudioTrackVector::value_type& cached_track) {
              return new_track->id() == cached_track->id();
            })) {
      audio_track_added_callback_(new_track.get(), stream_.get());
    }
  }

  // Find removed video tracks.
  for (const auto& cached_track : cached_video_tracks_) {
    if (absl::c_none_of(
            new_video_tracks,
            [cached_track](const VideoTrackVector::value_type& new_track) {
              return new_track->id() == cached_track->id();
            })) {
      video_track_removed_callback_(cached_track.get(), stream_.get());
    }
  }

  // Find added video tracks.
  for (const auto& new_track : new_video_tracks) {
    if (absl::c_none_of(
            cached_video_tracks_,
            [new_track](const VideoTrackVector::value_type& cached_track) {
              return new_track->id() == cached_track->id();
            })) {
      video_track_added_callback_(new_track.get(), stream_.get());
    }
  }

  cached_audio_tracks_ = new_audio_tracks;
  cached_video_tracks_ = new_video_tracks;
}

}  // namespace webrtc
