/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * 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. Neither the name of Google Inc. nor the names of its contributors
 *    may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "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 COPYRIGHT
 * OWNER OR CONTRIBUTORS 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 "modules/peerconnection/RTCIceCandidate.h"

#include "bindings/core/v8/ExceptionMessages.h"
#include "bindings/core/v8/ExceptionState.h"
#include "bindings/core/v8/ScriptValue.h"
#include "bindings/core/v8/V8ObjectBuilder.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContext.h"
#include "core/frame/UseCounter.h"
#include "modules/peerconnection/RTCIceCandidateInit.h"

namespace blink {

RTCIceCandidate* RTCIceCandidate::Create(
    ExecutionContext* context,
    const RTCIceCandidateInit& candidate_init,
    ExceptionState& exception_state) {
  if (!candidate_init.hasCandidate() || !candidate_init.candidate().length()) {
    exception_state.ThrowDOMException(
        kTypeMismatchError, ExceptionMessages::IncorrectPropertyType(
                                "candidate", "is not a string, or is empty."));
    return nullptr;
  }

  String sdp_mid;
  if (candidate_init.hasSdpMid())
    sdp_mid = candidate_init.sdpMid();

  // TODO(guidou): Change default value to -1. crbug.com/614958.
  unsigned short sdp_m_line_index = 0;
  if (candidate_init.hasSdpMLineIndex()) {
    sdp_m_line_index = candidate_init.sdpMLineIndex();
  } else {
    UseCounter::Count(context,
                      WebFeature::kRTCIceCandidateDefaultSdpMLineIndex);
  }

  return new RTCIceCandidate(WebRTCICECandidate(candidate_init.candidate(),
                                                sdp_mid, sdp_m_line_index));
}

RTCIceCandidate* RTCIceCandidate::Create(WebRTCICECandidate web_candidate) {
  return new RTCIceCandidate(web_candidate);
}

RTCIceCandidate::RTCIceCandidate(WebRTCICECandidate web_candidate)
    : web_candidate_(web_candidate) {}

String RTCIceCandidate::candidate() const {
  return web_candidate_.Candidate();
}

String RTCIceCandidate::sdpMid() const {
  return web_candidate_.SdpMid();
}

unsigned short RTCIceCandidate::sdpMLineIndex() const {
  return web_candidate_.SdpMLineIndex();
}

WebRTCICECandidate RTCIceCandidate::WebCandidate() const {
  return web_candidate_;
}

void RTCIceCandidate::setCandidate(String candidate) {
  web_candidate_.SetCandidate(candidate);
}

void RTCIceCandidate::setSdpMid(String sdp_mid) {
  web_candidate_.SetSdpMid(sdp_mid);
}

void RTCIceCandidate::setSdpMLineIndex(unsigned short sdp_m_line_index) {
  web_candidate_.SetSdpMLineIndex(sdp_m_line_index);
}

ScriptValue RTCIceCandidate::toJSONForBinding(ScriptState* script_state) {
  V8ObjectBuilder result(script_state);
  result.AddString("candidate", web_candidate_.Candidate());
  result.AddString("sdpMid", web_candidate_.SdpMid());
  result.AddNumber("sdpMLineIndex", web_candidate_.SdpMLineIndex());
  return result.GetScriptValue();
}

}  // namespace blink
