// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/renderer/media/media_stream_center.h"

#include <string>

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "content/renderer/media/media_stream_impl.h"
#include "content/renderer/media/media_stream_extra_data.h"
#include "content/renderer/render_view_impl.h"
#include "third_party/libjingle/source/talk/app/webrtc/jsep.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebICECandidateDescriptor.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamCenterClient.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamComponent.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamDescriptor.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamSource.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamSourcesRequest.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSessionDescriptionDescriptor.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"

namespace content {

static MediaStreamImpl* GetMediaStreamImpl(WebKit::WebFrame* web_frame) {
  RenderViewImpl* render_view = RenderViewImpl::FromWebView(web_frame->view());
  if (!render_view)
    return NULL;

  // TODO(perkj): Avoid this cast?
  return static_cast<MediaStreamImpl*>(render_view->userMediaClient());
}

static webrtc::MediaStreamInterface* GetNativeMediaStream(
    const WebKit::WebMediaStreamDescriptor& stream) {
  MediaStreamExtraData* extra_data =
      static_cast<MediaStreamExtraData*>(stream.extraData());
  if (extra_data && extra_data->remote_stream())
    return extra_data->remote_stream();

  if (extra_data && extra_data->local_stream())
    return extra_data->local_stream();

  // TODO(perkj): This can occur if a JS create a new MediaStream based on an
  // existing MediaStream.
  NOTIMPLEMENTED();
  return NULL;
}

template <class TrackList>
static webrtc::MediaStreamTrackInterface* GetTrack(
    const std::string& source_id,
    TrackList* tracks) {
  for (size_t i = 0; i < tracks->count(); ++i) {
    if (tracks->at(i)->label() == source_id)
      return tracks->at(i);
  }
  return NULL;
}

static webrtc::MediaStreamTrackInterface* GetNativeMediaStreamTrack(
      const WebKit::WebMediaStreamDescriptor& stream,
      const WebKit::WebMediaStreamComponent& component) {
  std::string source_id = UTF16ToUTF8(component.source().id());
  webrtc::MediaStreamInterface* native_stream = GetNativeMediaStream(stream);
  if (native_stream) {
    if (component.source().type() == WebKit::WebMediaStreamSource::TypeAudio) {
      return GetTrack<webrtc::AudioTracks>(
          source_id, native_stream->audio_tracks());
    }
    if (component.source().type() == WebKit::WebMediaStreamSource::TypeVideo) {
      return GetTrack<webrtc::VideoTracks>(
          source_id, native_stream->video_tracks());
    }
  }
  // TODO(perkj): This can occur if a JS create a new MediaStream based on an
  // existing MediaStream.
  NOTIMPLEMENTED();
  return NULL;
}

MediaStreamCenter::MediaStreamCenter(
    WebKit::WebMediaStreamCenterClient* client)
    : client_(client) {
}

void MediaStreamCenter::queryMediaStreamSources(
    const WebKit::WebMediaStreamSourcesRequest& request) {
  WebKit::WebVector<WebKit::WebMediaStreamSource> audioSources, videoSources;
  request.didCompleteQuery(audioSources, videoSources);
}

void MediaStreamCenter::didEnableMediaStreamTrack(
    const WebKit::WebMediaStreamDescriptor& stream,
    const WebKit::WebMediaStreamComponent& component) {
  webrtc::MediaStreamTrackInterface* track =
      GetNativeMediaStreamTrack(stream, component);
  if (track)
    track->set_enabled(true);
}

void MediaStreamCenter::didDisableMediaStreamTrack(
    const WebKit::WebMediaStreamDescriptor& stream,
    const WebKit::WebMediaStreamComponent& component) {
  webrtc::MediaStreamTrackInterface* track =
      GetNativeMediaStreamTrack(stream, component);
  if (track)
    track->set_enabled(false);
}

void MediaStreamCenter::didStopLocalMediaStream(
    const WebKit::WebMediaStreamDescriptor& stream) {
  DVLOG(1) << "MediaStreamCenter::didStopLocalMediaStream";
  WebKit::WebFrame* web_frame = WebKit::WebFrame::frameForCurrentContext();
  if (!web_frame)
    return;
  MediaStreamImpl* ms_impl = GetMediaStreamImpl(web_frame);
  if (ms_impl) {
    ms_impl->StopLocalMediaStream(stream);
    return;
  }

  NOTREACHED();
}

void MediaStreamCenter::didCreateMediaStream(
    WebKit::WebMediaStreamDescriptor& stream) {
  WebKit::WebFrame* web_frame = WebKit::WebFrame::frameForCurrentContext();
  if (!web_frame)
    return;
  MediaStreamImpl* ms_impl = GetMediaStreamImpl(web_frame);
  if (ms_impl) {
    ms_impl->CreateMediaStream(web_frame, &stream);
    return;
  }
  NOTREACHED();
}

WebKit::WebString MediaStreamCenter::constructSDP(
    const WebKit::WebICECandidateDescriptor& candidate) {
  int m_line_index = -1;
  if (!base::StringToInt(UTF16ToUTF8(candidate.label()), &m_line_index)) {
    LOG(ERROR) << "Invalid candidate label: " << UTF16ToUTF8(candidate.label());
    return WebKit::WebString();
  }
  scoped_ptr<webrtc::IceCandidateInterface> native_candidate(
      webrtc::CreateIceCandidate(UTF16ToUTF8(candidate.label()),
                                 m_line_index,
                                 UTF16ToUTF8(candidate.candidateLine())));
  std::string sdp;
  if (!native_candidate->ToString(&sdp))
    LOG(ERROR) << "Could not create SDP string";
  return UTF8ToUTF16(sdp);
}

WebKit::WebString MediaStreamCenter::constructSDP(
    const WebKit::WebSessionDescriptionDescriptor& description) {
  scoped_ptr<webrtc::SessionDescriptionInterface> native_desc(
      webrtc::CreateSessionDescription(UTF16ToUTF8(description.initialSDP())));
  if (!native_desc.get())
    return WebKit::WebString();

  for (size_t i = 0; i < description.numberOfAddedCandidates(); ++i) {
    WebKit::WebICECandidateDescriptor candidate = description.candidate(i);
    int m_line_index = -1;
    if (!base::StringToInt(UTF16ToUTF8(candidate.label()), &m_line_index)) {
      LOG(ERROR) << "Invalid candidate label: "
                 << UTF16ToUTF8(candidate.label());
      continue;
    }
    scoped_ptr<webrtc::IceCandidateInterface> native_candidate(
        webrtc::CreateIceCandidate(UTF16ToUTF8(candidate.label()),
                                   m_line_index,
                                   UTF16ToUTF8(candidate.candidateLine())));
    native_desc->AddCandidate(native_candidate.get());
  }

  std::string sdp;
  if (!native_desc->ToString(&sdp))
    LOG(ERROR) << "Could not create SDP string";
  return UTF8ToUTF16(sdp);
}

}  // namespace content
