/*
 * 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 "talk/app/webrtc/mediastreamproxy.h"
#include "talk/base/refcount.h"
#include "talk/base/scoped_ref_ptr.h"

namespace {

enum {
  MSG_SET_TRACKLIST_IMPLEMENTATION = 1,
  MSG_REGISTER_OBSERVER,
  MSG_UNREGISTER_OBSERVER,
  MSG_LABEL,
  MSG_ADD_AUDIO_TRACK,
  MSG_ADD_VIDEO_TRACK,
  MSG_READY_STATE,
  MSG_COUNT,
  MSG_AT
};

typedef talk_base::TypedMessageData<std::string*> LabelMessageData;
typedef talk_base::TypedMessageData<size_t> SizeTMessageData;
typedef talk_base::TypedMessageData<webrtc::ObserverInterface*>
    ObserverMessageData;
typedef talk_base::TypedMessageData<webrtc::MediaStreamInterface::ReadyState>
    ReadyStateMessageData;

template<typename T>
class MediaStreamTrackMessageData : public talk_base::MessageData {
 public:
  explicit MediaStreamTrackMessageData(T* track)
      : track_(track),
        result_(false) {
  }

  talk_base::scoped_refptr<T> track_;
  bool result_;
};

typedef MediaStreamTrackMessageData<webrtc::AudioTrackInterface>
    AudioTrackMsgData;
typedef MediaStreamTrackMessageData<webrtc::VideoTrackInterface>
    VideoTrackMsgData;

template <class TrackType>
class MediaStreamTrackAtMessageData : public talk_base::MessageData {
 public:
  explicit MediaStreamTrackAtMessageData(size_t index)
      : index_(index) {
  }

  size_t index_;
  talk_base::scoped_refptr<TrackType> track_;
};

class MediaStreamTrackListsMessageData : public talk_base::MessageData {
 public:
  talk_base::scoped_refptr<webrtc::AudioTracks> audio_tracks_;
  talk_base::scoped_refptr<webrtc::VideoTracks> video_tracks_;
};

}  // namespace anonymous

namespace webrtc {

talk_base::scoped_refptr<MediaStreamProxy> MediaStreamProxy::Create(
    const std::string& label,
    talk_base::Thread* signaling_thread) {
  ASSERT(signaling_thread != NULL);
  talk_base::RefCountedObject<MediaStreamProxy>* stream =
      new talk_base::RefCountedObject<MediaStreamProxy>(
          label, signaling_thread,
          reinterpret_cast<LocalMediaStreamInterface*>(NULL));
  return stream;
}

talk_base::scoped_refptr<MediaStreamProxy> MediaStreamProxy::Create(
    const std::string& label,
    talk_base::Thread* signaling_thread,
    LocalMediaStreamInterface* media_stream_impl) {
  ASSERT(signaling_thread != NULL);
  ASSERT(media_stream_impl != NULL);
  talk_base::RefCountedObject<MediaStreamProxy>* stream =
      new talk_base::RefCountedObject<MediaStreamProxy>(label, signaling_thread,
                                                media_stream_impl);
  return stream;
}

MediaStreamProxy::MediaStreamProxy(const std::string& label,
                                   talk_base::Thread* signaling_thread,
                                   LocalMediaStreamInterface* media_stream_impl)
    : signaling_thread_(signaling_thread),
      media_stream_impl_(media_stream_impl),
      audio_tracks_(new talk_base::RefCountedObject<
                        MediaStreamTrackListProxy<AudioTrackInterface> >(
                              signaling_thread_)),
      video_tracks_(new talk_base::RefCountedObject<
                        MediaStreamTrackListProxy<VideoTrackInterface> >(
                            signaling_thread_)) {
  if (media_stream_impl_ == NULL) {
    media_stream_impl_ = MediaStream::Create(label);
  }

  MediaStreamTrackListsMessageData tracklists;
  Send(MSG_SET_TRACKLIST_IMPLEMENTATION, &tracklists);
  audio_tracks_->SetImplementation(tracklists.audio_tracks_);
  video_tracks_->SetImplementation(tracklists.video_tracks_);
}

std::string MediaStreamProxy::label() const {
  if (!signaling_thread_->IsCurrent()) {
    std::string label;
    LabelMessageData msg(&label);
    Send(MSG_LABEL, &msg);
    return label;
  }
  return media_stream_impl_->label();
}

MediaStreamInterface::ReadyState MediaStreamProxy::ready_state() {
  if (!signaling_thread_->IsCurrent()) {
    ReadyStateMessageData msg(MediaStreamInterface::kInitializing);
    Send(MSG_READY_STATE, &msg);
    return msg.data();
  }
  return media_stream_impl_->ready_state();
}

void MediaStreamProxy::set_ready_state(
    MediaStreamInterface::ReadyState new_state) {
  if (!signaling_thread_->IsCurrent()) {
    // State should only be allowed to be changed from the signaling thread.
    ASSERT(!"Not Allowed!");
    return;
  }
  media_stream_impl_->set_ready_state(new_state);
}

bool MediaStreamProxy::AddTrack(AudioTrackInterface* track) {
  if (!signaling_thread_->IsCurrent()) {
    AudioTrackMsgData msg(track);
    Send(MSG_ADD_AUDIO_TRACK, &msg);
    return msg.result_;
  }
  return media_stream_impl_->AddTrack(track);
}

bool MediaStreamProxy::AddTrack(VideoTrackInterface* track) {
  if (!signaling_thread_->IsCurrent()) {
    VideoTrackMsgData msg(track);
    Send(MSG_ADD_VIDEO_TRACK, &msg);
    return msg.result_;
  }
  return media_stream_impl_->AddTrack(track);
}

void MediaStreamProxy::RegisterObserver(ObserverInterface* observer) {
  if (!signaling_thread_->IsCurrent()) {
    ObserverMessageData msg(observer);
    Send(MSG_REGISTER_OBSERVER, &msg);
    return;
  }
  media_stream_impl_->RegisterObserver(observer);
}

void MediaStreamProxy::UnregisterObserver(ObserverInterface* observer) {
  if (!signaling_thread_->IsCurrent()) {
    ObserverMessageData msg(observer);
    Send(MSG_UNREGISTER_OBSERVER, &msg);
    return;
  }
  media_stream_impl_->UnregisterObserver(observer);
}

void MediaStreamProxy::Send(uint32 id, talk_base::MessageData* data) const {
  signaling_thread_->Send(const_cast<MediaStreamProxy*>(this), id,
                          data);
}

// Implement MessageHandler
void MediaStreamProxy::OnMessage(talk_base::Message* msg) {
  talk_base::MessageData* data = msg->pdata;
  switch (msg->message_id) {
    case MSG_SET_TRACKLIST_IMPLEMENTATION: {
      MediaStreamTrackListsMessageData* lists =
          static_cast<MediaStreamTrackListsMessageData*>(data);
      lists->audio_tracks_ = media_stream_impl_->audio_tracks();
      lists->video_tracks_ = media_stream_impl_->video_tracks();
      break;
    }
    case MSG_REGISTER_OBSERVER: {
      ObserverMessageData* observer = static_cast<ObserverMessageData*>(data);
      media_stream_impl_->RegisterObserver(observer->data());
      break;
    }
    case MSG_UNREGISTER_OBSERVER: {
      ObserverMessageData* observer = static_cast<ObserverMessageData*>(data);
      media_stream_impl_->UnregisterObserver(observer->data());
      break;
    }
    case MSG_LABEL: {
      LabelMessageData * label = static_cast<LabelMessageData*>(data);
      *(label->data()) = media_stream_impl_->label();
      break;
    }
    case MSG_ADD_AUDIO_TRACK: {
      AudioTrackMsgData * track =
          static_cast<AudioTrackMsgData *>(data);
      track->result_ = media_stream_impl_->AddTrack(track->track_.get());
      break;
    }
    case MSG_ADD_VIDEO_TRACK: {
      VideoTrackMsgData * track =
          static_cast<VideoTrackMsgData *>(data);
      track->result_ = media_stream_impl_->AddTrack(track->track_.get());
      break;
    }
    case MSG_READY_STATE: {
      ReadyStateMessageData* state = static_cast<ReadyStateMessageData*>(data);
      state->data() = media_stream_impl_->ready_state();
      break;
    }
    default:
      ASSERT(!"Not Implemented!");
      break;
  }
}

template <class T>
MediaStreamProxy::MediaStreamTrackListProxy<T>::MediaStreamTrackListProxy(
    talk_base::Thread* signaling_thread)
    : signaling_thread_(signaling_thread) {
}

template <class T>
void MediaStreamProxy::MediaStreamTrackListProxy<T>::SetImplementation(
    MediaStreamTrackListInterface<T>* track_list) {
  track_list_ = track_list;
}

template <class T>
size_t MediaStreamProxy::MediaStreamTrackListProxy<T>::count() {
  if (!signaling_thread_->IsCurrent()) {
    SizeTMessageData msg(0u);
    Send(MSG_COUNT, &msg);
    return msg.data();
  }
  return track_list_->count();
}

template <class T>
T* MediaStreamProxy::MediaStreamTrackListProxy<T>::at(
    size_t index) {
  if (!signaling_thread_->IsCurrent()) {
    MediaStreamTrackAtMessageData<T> msg(index);
    Send(MSG_AT, &msg);
    return msg.track_;
  }
  return track_list_->at(index);
}

template <class T>
void MediaStreamProxy::MediaStreamTrackListProxy<T>::Send(
    uint32 id, talk_base::MessageData* data) const {
  signaling_thread_->Send(
      const_cast<MediaStreamProxy::MediaStreamTrackListProxy<T>*>(
          this), id, data);
}

// Implement MessageHandler
template <class T>
void MediaStreamProxy::MediaStreamTrackListProxy<T>::OnMessage(
    talk_base::Message* msg) {
  talk_base::MessageData* data = msg->pdata;
  switch (msg->message_id) {
    case MSG_COUNT: {
      SizeTMessageData* count = static_cast<SizeTMessageData*>(data);
      count->data() = track_list_->count();
      break;
    }
    case MSG_AT: {
      MediaStreamTrackAtMessageData<T>* track =
          static_cast<MediaStreamTrackAtMessageData<T>*>(data);
      track->track_ = track_list_->at(track->index_);
      break;
    }
    default:
      ASSERT(!"Not Implemented!");
      break;
  }
}

}  // namespace webrtc
