// Copyright 2015 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 "modules/audio_output_devices/HTMLMediaElementAudioOutputDevice.h"

#include "bindings/core/v8/ScriptPromiseResolver.h"
#include "bindings/core/v8/ScriptState.h"
#include "core/dom/DOMException.h"
#include "core/dom/ExecutionContext.h"
#include "modules/audio_output_devices/AudioOutputDeviceClient.h"
#include "modules/audio_output_devices/SetSinkIdCallbacks.h"
#include "public/platform/WebSecurityOrigin.h"
#include "wtf/PtrUtil.h"
#include <memory>

namespace blink {

namespace {

class SetSinkIdResolver : public ScriptPromiseResolver {
  WTF_MAKE_NONCOPYABLE(SetSinkIdResolver);

 public:
  static SetSinkIdResolver* create(ScriptState*,
                                   HTMLMediaElement&,
                                   const String& sinkId);
  ~SetSinkIdResolver() override = default;
  void startAsync();

  DECLARE_VIRTUAL_TRACE();

 private:
  SetSinkIdResolver(ScriptState*, HTMLMediaElement&, const String& sinkId);
  void timerFired(TimerBase*);

  Member<HTMLMediaElement> m_element;
  String m_sinkId;
  Timer<SetSinkIdResolver> m_timer;
};

SetSinkIdResolver* SetSinkIdResolver::create(ScriptState* scriptState,
                                             HTMLMediaElement& element,
                                             const String& sinkId) {
  SetSinkIdResolver* resolver =
      new SetSinkIdResolver(scriptState, element, sinkId);
  resolver->suspendIfNeeded();
  resolver->keepAliveWhilePending();
  return resolver;
}

SetSinkIdResolver::SetSinkIdResolver(ScriptState* scriptState,
                                     HTMLMediaElement& element,
                                     const String& sinkId)
    : ScriptPromiseResolver(scriptState),
      m_element(element),
      m_sinkId(sinkId),
      m_timer(this, &SetSinkIdResolver::timerFired) {}

void SetSinkIdResolver::startAsync() {
  m_timer.startOneShot(0, BLINK_FROM_HERE);
}

void SetSinkIdResolver::timerFired(TimerBase* timer) {
  ExecutionContext* context = getExecutionContext();
  ASSERT(context && context->isDocument());
  std::unique_ptr<SetSinkIdCallbacks> callbacks =
      wrapUnique(new SetSinkIdCallbacks(this, *m_element, m_sinkId));
  WebMediaPlayer* webMediaPlayer = m_element->webMediaPlayer();
  if (webMediaPlayer) {
    // Using release() to transfer ownership because |webMediaPlayer| is a
    // platform object that takes raw pointers.
    webMediaPlayer->setSinkId(m_sinkId,
                              WebSecurityOrigin(context->getSecurityOrigin()),
                              callbacks.release());
  } else {
    if (AudioOutputDeviceClient* client =
            AudioOutputDeviceClient::from(context)) {
      client->checkIfAudioSinkExistsAndIsAuthorized(context, m_sinkId,
                                                    std::move(callbacks));
    } else {
      // The context has been detached. Impossible to get a security origin to
      // check.
      ASSERT(context->activeDOMObjectsAreStopped());
      reject(DOMException::create(
          SecurityError,
          "Impossible to authorize device for detached context"));
    }
  }
}

DEFINE_TRACE(SetSinkIdResolver) {
  visitor->trace(m_element);
  ScriptPromiseResolver::trace(visitor);
}

}  // namespace

HTMLMediaElementAudioOutputDevice::HTMLMediaElementAudioOutputDevice()
    : m_sinkId("") {}

String HTMLMediaElementAudioOutputDevice::sinkId(HTMLMediaElement& element) {
  HTMLMediaElementAudioOutputDevice& aodElement =
      HTMLMediaElementAudioOutputDevice::from(element);
  return aodElement.m_sinkId;
}

void HTMLMediaElementAudioOutputDevice::setSinkId(const String& sinkId) {
  m_sinkId = sinkId;
}

ScriptPromise HTMLMediaElementAudioOutputDevice::setSinkId(
    ScriptState* scriptState,
    HTMLMediaElement& element,
    const String& sinkId) {
  SetSinkIdResolver* resolver =
      SetSinkIdResolver::create(scriptState, element, sinkId);
  ScriptPromise promise = resolver->promise();
  if (sinkId == HTMLMediaElementAudioOutputDevice::sinkId(element))
    resolver->resolve();
  else
    resolver->startAsync();

  return promise;
}

const char* HTMLMediaElementAudioOutputDevice::supplementName() {
  return "HTMLMediaElementAudioOutputDevice";
}

HTMLMediaElementAudioOutputDevice& HTMLMediaElementAudioOutputDevice::from(
    HTMLMediaElement& element) {
  HTMLMediaElementAudioOutputDevice* supplement =
      static_cast<HTMLMediaElementAudioOutputDevice*>(
          Supplement<HTMLMediaElement>::from(element, supplementName()));
  if (!supplement) {
    supplement = new HTMLMediaElementAudioOutputDevice();
    provideTo(element, supplementName(), supplement);
  }
  return *supplement;
}

DEFINE_TRACE(HTMLMediaElementAudioOutputDevice) {
  Supplement<HTMLMediaElement>::trace(visitor);
}

}  // namespace blink
