/*
 * libjingle
 * Copyright 2011, 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.
 */

#include <string>

#include "talk/app/webrtc/mediastreamproxy.h"
#include "talk/app/webrtc/mediastreamtrackproxy.h"
#include "talk/base/refcount.h"
#include "talk/base/scoped_ptr.h"
#include "talk/base/thread.h"
#include "talk/base/gunit.h"
#include "testing/base/public/gmock.h"

static const char kStreamLabel1[] = "local_stream_1";
static const char kVideoTrackLabel[] = "dummy_video_cam_1";
static const char kAudioTrackLabel[] = "dummy_microphone_1";

using talk_base::scoped_refptr;
using ::testing::Exactly;

namespace {

class ReadyStateMessageData : public talk_base::MessageData {
 public:
  ReadyStateMessageData(
      webrtc::MediaStreamInterface* stream,
      webrtc::MediaStreamInterface::ReadyState new_state)
      : stream_(stream),
        ready_state_(new_state) {
  }

  scoped_refptr<webrtc::MediaStreamInterface> stream_;
  webrtc::MediaStreamInterface::ReadyState ready_state_;
};

class TrackStateMessageData : public talk_base::MessageData {
 public:
  TrackStateMessageData(
      webrtc::MediaStreamTrackInterface* track,
      webrtc::MediaStreamTrackInterface::TrackState state)
      : track_(track),
        state_(state) {
  }

  scoped_refptr<webrtc::MediaStreamTrackInterface> track_;
  webrtc::MediaStreamTrackInterface::TrackState state_;
};

}  // namespace anonymous

namespace webrtc {

// Helper class to test Observer.
class MockObserver : public ObserverInterface {
 public:
  explicit MockObserver(talk_base::Thread* signaling_thread)
      : signaling_thread_(signaling_thread) {
  }

  MOCK_METHOD0(DoOnChanged, void());
  virtual void OnChanged() {
    ASSERT_TRUE(talk_base::Thread::Current() == signaling_thread_);
    DoOnChanged();
  }
 private:
  talk_base::Thread* signaling_thread_;
};

class MockMediaStream: public LocalMediaStreamInterface {
 public:
  MockMediaStream(const std::string& label, talk_base::Thread* signaling_thread)
      : stream_impl_(MediaStream::Create(label)),
        signaling_thread_(signaling_thread) {
  }
  virtual void RegisterObserver(webrtc::ObserverInterface* observer) {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    stream_impl_->RegisterObserver(observer);
  }
  virtual void UnregisterObserver(webrtc::ObserverInterface* observer) {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    stream_impl_->UnregisterObserver(observer);
  }
  virtual std::string label() const {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    return stream_impl_->label();
  }
  virtual AudioTracks* audio_tracks() {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    return stream_impl_->audio_tracks();
  }
  virtual VideoTracks* video_tracks() {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    return stream_impl_->video_tracks();
  }
  virtual ReadyState ready_state() {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    return stream_impl_->ready_state();
  }
  virtual void set_ready_state(ReadyState state) {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    return stream_impl_->set_ready_state(state);
  }
  virtual bool AddTrack(AudioTrackInterface* audio_track) {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    return stream_impl_->AddTrack(audio_track);
  }
  virtual bool AddTrack(VideoTrackInterface* video_track) {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    return stream_impl_->AddTrack(video_track);
  }

 private:
  scoped_refptr<MediaStream> stream_impl_;
  talk_base::Thread* signaling_thread_;
};

template <class T>
class MockMediaStreamTrack: public T {
 public:
  MockMediaStreamTrack(T* implementation,
                       talk_base::Thread* signaling_thread)
      : track_impl_(implementation),
        signaling_thread_(signaling_thread) {
  }
  virtual void RegisterObserver(webrtc::ObserverInterface* observer) {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    track_impl_->RegisterObserver(observer);
  }
  virtual void UnregisterObserver(webrtc::ObserverInterface* observer) {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    track_impl_->UnregisterObserver(observer);
  }
  virtual std::string kind() const {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    return track_impl_->kind();
  }
  virtual std::string label() const {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    return track_impl_->label();
  }
  virtual bool enabled() const {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    return track_impl_->enabled();
  }
  virtual MediaStreamTrackInterface::TrackState state() const {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    return track_impl_->state();
  }
  virtual bool set_enabled(bool enabled) {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    return track_impl_->set_enabled(enabled);
  }
  virtual bool set_state(webrtc::MediaStreamTrackInterface::TrackState state) {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    return track_impl_->set_state(state);
  }

 protected:
  scoped_refptr<T> track_impl_;
  talk_base::Thread* signaling_thread_;
};

class MockLocalVideoTrack
    : public MockMediaStreamTrack<LocalVideoTrackInterface> {
 public:
    MockLocalVideoTrack(LocalVideoTrackInterface* implementation,
                        talk_base::Thread* signaling_thread)
        : MockMediaStreamTrack<LocalVideoTrackInterface>(implementation,
                                                         signaling_thread) {
    }
  virtual void SetRenderer(webrtc::VideoRendererWrapperInterface* renderer) {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    track_impl_->SetRenderer(renderer);
  }
  virtual VideoRendererWrapperInterface* GetRenderer() {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    return track_impl_->GetRenderer();
  }
  virtual cricket::VideoCapturer* GetVideoCapture() {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    return track_impl_->GetVideoCapture();
  }
};

class MockLocalAudioTrack
    : public MockMediaStreamTrack<LocalAudioTrackInterface> {
 public:
  MockLocalAudioTrack(LocalAudioTrackInterface* implementation,
                      talk_base::Thread* signaling_thread)
    : MockMediaStreamTrack<LocalAudioTrackInterface>(implementation,
                                                     signaling_thread) {
  }

  virtual AudioDeviceModule* GetAudioDevice() {
    EXPECT_EQ(talk_base::Thread::Current(), signaling_thread_);
    return track_impl_->GetAudioDevice();
  }
};

class MediaStreamTest: public testing::Test,
                       public talk_base::MessageHandler {
 protected:
  virtual void SetUp() {
    signaling_thread_ .reset(new talk_base::Thread());
    ASSERT_TRUE(signaling_thread_->Start());

    std::string label(kStreamLabel1);
    // Create a stream proxy object that uses our mocked
    // version of a LocalMediaStream.
    scoped_refptr<MockMediaStream> mock_stream(
        new talk_base::RefCountedObject<MockMediaStream>(label,
                                                 signaling_thread_.get()));
    stream_ = MediaStreamProxy::Create(label, signaling_thread_.get(),
                                       mock_stream);
    ASSERT_TRUE(stream_.get() != NULL);
    EXPECT_EQ(label, stream_->label());
    EXPECT_EQ(MediaStreamInterface::kInitializing, stream_->ready_state());

    // Create a video track proxy object that uses our mocked
    // version of a LocalVideoTrack
    scoped_refptr<VideoTrack> video_track_impl(
        VideoTrack::CreateLocal(kVideoTrackLabel, NULL));
    scoped_refptr<MockLocalVideoTrack> mock_videotrack(
        new talk_base::RefCountedObject<MockLocalVideoTrack>(video_track_impl,
                                                     signaling_thread_.get()));
    video_track_ = VideoTrackProxy::CreateLocal(mock_videotrack,
                                                signaling_thread_.get());

    ASSERT_TRUE(video_track_.get() != NULL);
    EXPECT_EQ(MediaStreamTrackInterface::kInitializing, video_track_->state());

    // Create an audio track proxy object that uses our mocked
    // version of a LocalAudioTrack
    scoped_refptr<AudioTrack> audio_track_impl(
        AudioTrack::CreateLocal(kAudioTrackLabel, NULL));
    scoped_refptr<MockLocalAudioTrack> mock_audiotrack(
        new talk_base::RefCountedObject<MockLocalAudioTrack>(audio_track_impl,
                                                     signaling_thread_.get()));
    audio_track_ = AudioTrackProxy::CreateLocal(mock_audiotrack,
                                                signaling_thread_.get());

    ASSERT_TRUE(audio_track_.get() != NULL);
    EXPECT_EQ(MediaStreamTrackInterface::kInitializing, audio_track_->state());
  }

  enum {
    MSG_SET_READYSTATE,
    MSG_SET_TRACKSTATE,
  };

  // Set the ready state on the signaling thread.
  // State can only be changed on the signaling thread.
  void SetReadyState(MediaStreamInterface* stream,
                     MediaStreamInterface::ReadyState new_state) {
    ReadyStateMessageData state(stream, new_state);
    signaling_thread_->Send(this, MSG_SET_READYSTATE, &state);
  }

  // Set the track state on the signaling thread.
  // State can only be changed on the signaling thread.
  void SetTrackState(MediaStreamTrackInterface* track,
                     MediaStreamTrackInterface::TrackState new_state) {
    TrackStateMessageData state(track, new_state);
    signaling_thread_->Send(this, MSG_SET_TRACKSTATE, &state);
  }

  talk_base::scoped_ptr<talk_base::Thread> signaling_thread_;
  scoped_refptr<LocalMediaStreamInterface> stream_;
  scoped_refptr<LocalVideoTrackInterface> video_track_;
  scoped_refptr<LocalAudioTrackInterface> audio_track_;

 private:
  // Implements talk_base::MessageHandler.
  virtual void OnMessage(talk_base::Message* msg) {
    switch (msg->message_id) {
      case MSG_SET_READYSTATE: {
        ReadyStateMessageData* state =
            static_cast<ReadyStateMessageData*>(msg->pdata);
        state->stream_->set_ready_state(state->ready_state_);
        break;
      }
      case MSG_SET_TRACKSTATE: {
        TrackStateMessageData* state =
            static_cast<TrackStateMessageData*>(msg->pdata);
        state->track_->set_state(state->state_);
        break;
      }
      default:
        break;
    }
  }
};

TEST_F(MediaStreamTest, CreateLocalStream) {
  EXPECT_TRUE(stream_->AddTrack(video_track_));
  EXPECT_TRUE(stream_->AddTrack(audio_track_));

  ASSERT_EQ(1u, stream_->video_tracks()->count());
  ASSERT_EQ(1u, stream_->audio_tracks()->count());

  // Verify the video track.
  scoped_refptr<webrtc::MediaStreamTrackInterface> track(
      stream_->video_tracks()->at(0));
  EXPECT_EQ(0, track->label().compare(kVideoTrackLabel));
  EXPECT_TRUE(track->enabled());

  // Verify the audio track.
  track = stream_->audio_tracks()->at(0);
  EXPECT_EQ(0, track->label().compare(kAudioTrackLabel));
  EXPECT_TRUE(track->enabled());
}

TEST_F(MediaStreamTest, ChangeStreamState) {
  MockObserver observer(signaling_thread_.get());
  stream_->RegisterObserver(&observer);

  EXPECT_CALL(observer, DoOnChanged())
      .Times(Exactly(1));
  SetReadyState(stream_, MediaStreamInterface::kLive);

  EXPECT_EQ(MediaStreamInterface::kLive, stream_->ready_state());
  // It should not be possible to add
  // streams when the state has changed to live.
  EXPECT_FALSE(stream_->AddTrack(audio_track_));
  EXPECT_EQ(0u, stream_->audio_tracks()->count());
}

TEST_F(MediaStreamTest, ChangeVideoTrack) {
  MockObserver observer(signaling_thread_.get());
  video_track_->RegisterObserver(&observer);

  EXPECT_CALL(observer, DoOnChanged())
      .Times(Exactly(1));
  video_track_->set_enabled(false);
  EXPECT_FALSE(video_track_->state());

  EXPECT_CALL(observer, DoOnChanged())
      .Times(Exactly(1));
  SetTrackState(video_track_, MediaStreamTrackInterface::kLive);
  EXPECT_EQ(MediaStreamTrackInterface::kLive, video_track_->state());

  EXPECT_CALL(observer, DoOnChanged())
      .Times(Exactly(1));
  scoped_refptr<VideoRendererWrapperInterface> renderer(
      CreateVideoRenderer(NULL));
  video_track_->SetRenderer(renderer.get());
  EXPECT_TRUE(renderer.get() == video_track_->GetRenderer());
}

TEST_F(MediaStreamTest, ChangeAudioTrack) {
  MockObserver observer(signaling_thread_.get());
  audio_track_->RegisterObserver(&observer);

  EXPECT_CALL(observer, DoOnChanged())
      .Times(Exactly(1));
  audio_track_->set_enabled(false);
  EXPECT_FALSE(audio_track_->enabled());

  EXPECT_CALL(observer, DoOnChanged())
      .Times(Exactly(1));
  SetTrackState(audio_track_, MediaStreamTrackInterface::kLive);
  EXPECT_EQ(MediaStreamTrackInterface::kLive, audio_track_->state());
}

}  // namespace webrtc
