/*
 * 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/webrtcsession.h"

#include "talk/app/webrtc/mediastream.h"
#include "talk/app/webrtc/peerconnection.h"
#include "talk/app/webrtc/peerconnectionsignaling.h"
#include "talk/base/helpers.h"
#include "talk/base/logging.h"
#include "talk/session/phone/channel.h"
#include "talk/session/phone/channelmanager.h"
#include "talk/session/phone/mediasession.h"
#include "talk/session/phone/videocapturer.h"

using cricket::MediaContentDescription;

namespace webrtc {

enum {
  MSG_CANDIDATE_TIMEOUT = 101,
};

// We allow 30 seconds to establish a connection, otherwise it's an error.
static const int kCallSetupTimeout = 30 * 1000;
// Session will accept one candidate per transport channel and dropping other
// candidates generated for that channel. During the session initialization
// one cricket::VoiceChannel and one cricket::VideoChannel will be created with
// rtcp enabled.
static const size_t kAllowedCandidates = 4;
// TODO - These are magic string used by cricket::VideoChannel.
// These should be moved to a common place.
static const char kRtpVideoChannelStr[] = "video_rtp";
static const char kRtcpVideoChannelStr[] = "video_rtcp";

// Constants for setting the default encoder size.
// TODO: Implement proper negotiation of video resolution.
static const int kDefaultVideoCodecId = 100;
static const int kDefaultVideoCodecFramerate = 30;
static const char kDefaultVideoCodecName[] = "VP8";
static const int kDefaultVideoCodecWidth = 640;
static const int kDefaultVideoCodecHeight = 480;

// MediaSessionDescriptionFactory always creates one StreamParams for
// legacy reasons even if options don't contain any streams.
// We need to remove it in that case since here options contains all streams
// we want to send.
// TODO: This is placed in the wrong file. Can we solve this problem by
// adding a method MediaSessionDescriptionFactory::set_add_legacy_streams(false)
// to prevent it from creating legacy streams.
static void RemoveLegacyStreams(const cricket::MediaSessionOptions& options,
                                cricket::SessionDescription* description) {
  bool found_audio_stream = false;
  bool found_video_stream = false;
  for (cricket::MediaSessionOptions::Streams::const_iterator it =
      options.streams.begin();
       it != options.streams.end(); ++it) {
    if (it->type == cricket::MEDIA_TYPE_AUDIO)
      found_audio_stream = true;

    if (it->type == cricket::MEDIA_TYPE_VIDEO)
      found_video_stream = true;
  }
  if (found_audio_stream == false) {
    const cricket::ContentInfo* audio_info =
        cricket::GetFirstAudioContent(description);
      if (audio_info) {
        const cricket::MediaContentDescription* const_media_desc =
            static_cast<const cricket::MediaContentDescription*>(
            audio_info->description);
        cricket::MediaContentDescription* media_desc =
            const_cast<cricket::MediaContentDescription*> (const_media_desc);
        media_desc->mutable_streams().clear();
      }
  }
  if (found_video_stream == false) {
    const cricket::ContentInfo* video_info =
        cricket::GetFirstVideoContent(description);
      if (video_info) {
        const cricket::MediaContentDescription* const_media_desc =
            static_cast<const cricket::MediaContentDescription*>(
                video_info->description);
        cricket::MediaContentDescription* media_desc =
               const_cast<cricket::MediaContentDescription*> (const_media_desc);
        media_desc->mutable_streams().clear();
      }
  }
}

WebRtcSession::WebRtcSession(cricket::ChannelManager* channel_manager,
                             talk_base::Thread* signaling_thread,
                             talk_base::Thread* worker_thread,
                             cricket::PortAllocator* port_allocator)
    : cricket::BaseSession(signaling_thread, worker_thread, port_allocator,
          talk_base::ToString(talk_base::CreateRandomId()),
          cricket::NS_JINGLE_RTP, true),
      channel_manager_(channel_manager),
      observer_(NULL),
      session_desc_factory_(channel_manager) {
}

WebRtcSession::~WebRtcSession() {
  Terminate();
}

bool WebRtcSession::Initialize() {
  // By default SRTP-SDES is enabled in WebRtc.
  set_secure_policy(cricket::SEC_REQUIRED);

  const cricket::VideoCodec default_codec(kDefaultVideoCodecId,
      kDefaultVideoCodecName, kDefaultVideoCodecWidth, kDefaultVideoCodecHeight,
      kDefaultVideoCodecFramerate, 0);
  channel_manager_->SetDefaultVideoEncoderConfig(
      cricket::VideoEncoderConfig(default_codec));

  return CreateChannels();
}

void WebRtcSession::Terminate() {
  if (voice_channel_.get()) {
    channel_manager_->DestroyVoiceChannel(voice_channel_.release());
  }
  if (video_channel_.get()) {
    channel_manager_->DestroyVideoChannel(video_channel_.release());
  }
}

void WebRtcSession::set_secure_policy(
    cricket::SecureMediaPolicy secure_policy) {
  session_desc_factory_.set_secure(secure_policy);
}

bool WebRtcSession::CreateChannels() {
  voice_channel_.reset(channel_manager_->CreateVoiceChannel(
      this, cricket::CN_AUDIO, true));
  if (!voice_channel_.get()) {
    LOG(LS_ERROR) << "Failed to create voice channel";
    return false;
  }

  video_channel_.reset(channel_manager_->CreateVideoChannel(
      this, cricket::CN_VIDEO, true, voice_channel_.get()));
  if (!video_channel_.get()) {
    LOG(LS_ERROR) << "Failed to create video channel";
    return false;
  }

  // TransportProxies and TransportChannels will be created when
  // CreateVoiceChannel and CreateVideoChannel are called.
  // Try connecting all transport channels. This is necessary to generate
  // ICE candidates.
  SpeculativelyConnectAllTransportChannels();
  return true;
}

// Enabling voice and video channel.
void WebRtcSession::EnableChannels() {
  if (!voice_channel_->enabled())
    voice_channel_->Enable(true);

  if (!video_channel_->enabled())
    video_channel_->Enable(true);
}

void WebRtcSession::OnTransportRequestSignaling(
    cricket::Transport* transport) {
  ASSERT(signaling_thread()->IsCurrent());
  transport->OnSignalingReady();
}

void WebRtcSession::OnTransportConnecting(cricket::Transport* transport) {
  ASSERT(signaling_thread()->IsCurrent());
  // start monitoring for the write state of the transport.
  OnTransportWritable(transport);
}

void WebRtcSession::OnTransportWritable(cricket::Transport* transport) {
  ASSERT(signaling_thread()->IsCurrent());
  // If the transport is not in writable state, start a timer to monitor
  // the state. If the transport doesn't become writable state in 30 seconds
  // then we are assuming call can't be continued.
  signaling_thread()->Clear(this, MSG_CANDIDATE_TIMEOUT);
  if (transport->HasChannels() && !transport->writable()) {
    signaling_thread()->PostDelayed(
        kCallSetupTimeout, this, MSG_CANDIDATE_TIMEOUT);
  }
}

void WebRtcSession::OnTransportCandidatesReady(
    cricket::Transport* transport, const cricket::Candidates& candidates) {
  ASSERT(signaling_thread()->IsCurrent());
  // Drop additional candidates for the same channel;
  // local_candidates_ will have one candidate per channel.
  if (local_candidates_.size() == kAllowedCandidates)
    return;
  InsertTransportCandidates(candidates);
  if (local_candidates_.size() == kAllowedCandidates && observer_) {
    observer_->OnCandidatesReady(local_candidates_);
  }
}

void WebRtcSession::OnTransportChannelGone(cricket::Transport* transport,
                                           const std::string& name) {
  ASSERT(signaling_thread()->IsCurrent());
}

void WebRtcSession::OnMessage(talk_base::Message* msg) {
  switch (msg->message_id) {
    case MSG_CANDIDATE_TIMEOUT:
      LOG(LS_ERROR) << "Transport is not in writable state.";
      SignalError();
      break;
    default:
      break;
  }
}

void WebRtcSession::InsertTransportCandidates(
    const cricket::Candidates& candidates) {
  for (cricket::Candidates::const_iterator citer = candidates.begin();
       citer != candidates.end(); ++citer) {
    // Find candidates by name, if this channel name not exists in local
    // candidate list, store it.
    if (!CheckCandidate((*citer).name())) {
      local_candidates_.push_back(*citer);
    }
  }
}

// Check transport candidate already available for transport channel as only
// one cricket::Candidate allower per channel.
bool WebRtcSession::CheckCandidate(const std::string& name) {
  bool ret = false;
  for (cricket::Candidates::iterator iter = local_candidates_.begin();
       iter != local_candidates_.end(); ++iter) {
    if ((*iter).name().compare(name) == 0) {
      ret = true;
      break;
    }
  }
  return ret;
}

bool WebRtcSession::SetCaptureDevice(const std::string& name,
                                     cricket::VideoCapturer* camera) {
  // should be called from a signaling thread
  ASSERT(signaling_thread()->IsCurrent());

  // TODO: Refactor this when there is support for multiple cameras.
  const uint32 dummy_ssrc = 0;
  if (!channel_manager_->SetVideoCapturer(camera, dummy_ssrc)) {
    LOG(LS_ERROR) << "Failed to set capture device.";
    return false;
  }

  // Start the capture
  cricket::CaptureResult ret = channel_manager_->SetVideoCapture(true);
  if (ret != cricket::CR_SUCCESS && ret != cricket::CR_PENDING) {
    LOG(LS_ERROR) << "Failed to start the capture device.";
    return false;
  }

  return true;
}

void WebRtcSession::SetLocalRenderer(const std::string& name,
                                     cricket::VideoRenderer* renderer) {
  ASSERT(signaling_thread()->IsCurrent());
  // TODO: Fix SetLocalRenderer.
  // video_channel_->SetLocalRenderer(0, renderer);
}

void WebRtcSession::SetRemoteRenderer(const std::string& name,
                                      cricket::VideoRenderer* renderer) {
  ASSERT(signaling_thread()->IsCurrent());

  const cricket::ContentInfo* video_info =
      cricket::GetFirstVideoContent(remote_description());
  if (!video_info) {
    LOG(LS_ERROR) << "Video not received in this call";
  }

  const cricket::MediaContentDescription* video_content =
      static_cast<const cricket::MediaContentDescription*>(
          video_info->description);
  cricket::StreamParams stream;
  if (cricket::GetStreamByNickAndName(video_content->streams(), "", name,
                                      &stream)) {
    video_channel_->SetRenderer(stream.first_ssrc(), renderer);
  } else {
    // Allow that |stream| does not exist if renderer is null but assert
    // otherwise.
    VERIFY(renderer == NULL);
  }
}

cricket::SessionDescription* WebRtcSession::CreateOffer(
    const cricket::MediaSessionOptions& options) {
  if (!options.has_video) {
    LOG(LS_WARNING) << "To receive video, has_video flag must be set to true";
    return NULL;
  }

  cricket::SessionDescription* offer(
      session_desc_factory_.CreateOffer(options, local_description()));

  // MediaSessionDescriptionFactory always creates one StreamParams for
  // legacy reasons even if options don't contain any streams.
  // We need to remove it in that case since here options contains all streams
  // we want to send.
  RemoveLegacyStreams(options, offer);
  return offer;
}

cricket::SessionDescription* WebRtcSession::CreateAnswer(
    const cricket::SessionDescription* offer,
    const cricket::MediaSessionOptions& options) {
  cricket::SessionDescription* answer(
      session_desc_factory_.CreateAnswer(offer, options,
                                         local_description()));
  // MediaSessionDescriptionFactory always creates one StreamParams for
  // legacy reasons even if options don't contain any streams.
  // We need to remove it in that case since here options contains all streams
  // we want to send.
  RemoveLegacyStreams(options, answer);
  return answer;
}

void WebRtcSession::SetLocalDescription(const cricket::SessionDescription* desc,
                                        cricket::ContentAction type) {
  if (!VERIFY((type == cricket::CA_ANSWER &&
               state() == STATE_RECEIVEDINITIATE) ||
              (type == cricket::CA_OFFER &&
               (state() != STATE_RECEIVEDINITIATE &&
                state() != STATE_SENTINITIATE)))) {
    LOG(LS_ERROR) << "SetLocalDescription called with action in wrong state, "
                  << "action: " << type << " state: " << state();
    return;
  }

  set_local_description(desc);
  if (type == cricket::CA_ANSWER) {
    EnableChannels();
    SetState(STATE_SENTACCEPT);
  } else {
    SetState(STATE_SENTINITIATE);
  }
}

void WebRtcSession::SetRemoteDescription(cricket::SessionDescription* desc,
                                         cricket::ContentAction type) {
  if (!VERIFY((type == cricket::CA_ANSWER &&
               state() == STATE_SENTINITIATE) ||
              (type == cricket::CA_OFFER &&
               (state() != STATE_RECEIVEDINITIATE &&
                state() != STATE_SENTINITIATE)))) {
    LOG(LS_ERROR) << "SetRemoteDescription called with action in wrong state, "
                  << "action: " << type << " state: " << state();
    return;
  }
  set_remote_description(desc);

  if (type  == cricket::CA_ANSWER) {
    EnableChannels();
    SetState(STATE_RECEIVEDACCEPT);
  } else {
    SetState(STATE_RECEIVEDINITIATE);
  }
}

void WebRtcSession::SetRemoteCandidates(
    const cricket::Candidates& candidates) {
  // First partition the candidates for the proxies. During creation of channels
  // we created CN_AUDIO (audio) and CN_VIDEO (video) proxies.
  cricket::Candidates audio_candidates;
  cricket::Candidates video_candidates;
  for (cricket::Candidates::const_iterator citer = candidates.begin();
       citer != candidates.end(); ++citer) {
    if (((*citer).name().compare(kRtpVideoChannelStr) == 0) ||
        ((*citer).name().compare(kRtcpVideoChannelStr)) == 0) {
      // Candidate names for video rtp and rtcp channel
      video_candidates.push_back(*citer);
    } else {
      // Candidates for audio rtp and rtcp channel
      // Channel name will be "rtp" and "rtcp"
      audio_candidates.push_back(*citer);
    }
  }

  // TODO: Justins comment:This is bad encapsulation, suggest we add a
  // helper to BaseSession to allow us to
  // pass in candidates without touching the transport proxies.
  if (!audio_candidates.empty()) {
    cricket::TransportProxy* audio_proxy = GetTransportProxy(cricket::CN_AUDIO);
    if (audio_proxy) {
      // CompleteNegotiation will set actual impl's in Proxy.
      if (!audio_proxy->negotiated())
        audio_proxy->CompleteNegotiation();
      // TODO - Add a interface to TransportProxy to accept
      // remote candidate list.
      audio_proxy->impl()->OnRemoteCandidates(audio_candidates);
    } else {
      LOG(LS_INFO) << "No audio TransportProxy exists";
    }
  }

  if (!video_candidates.empty()) {
    cricket::TransportProxy* video_proxy = GetTransportProxy(cricket::CN_VIDEO);
    if (video_proxy) {
      // CompleteNegotiation will set actual impl's in Proxy.
      if (!video_proxy->negotiated())
        video_proxy->CompleteNegotiation();
      // TODO - Add a interface to TransportProxy to accept
      // remote candidate list.
      video_proxy->impl()->OnRemoteCandidates(video_candidates);
    } else {
      LOG(LS_INFO) << "No video TransportProxy exists";
    }
  }
}

}  // namespace webrtc
