/*
 * Copyright (C) 2019 Apple 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

#pragma once

#if ENABLE(WIRELESS_PLAYBACK_TARGET)

#include "ActiveDOMObject.h"
#include "EventTarget.h"
#include <wtf/HashMap.h>
#include <wtf/Ref.h>
#include <wtf/RefCounted.h>

namespace WebCore {

class DeferredPromise;
class HTMLMediaElement;
class MediaPlaybackTarget;
class Node;
class RemotePlaybackAvailabilityCallback;

class RemotePlayback final : public RefCounted<RemotePlayback>, public ActiveDOMObject, public EventTargetWithInlineData {
    WTF_MAKE_ISO_ALLOCATED(RemotePlayback);
public:
    static Ref<RemotePlayback> create(HTMLMediaElement&);
    ~RemotePlayback();

    void watchAvailability(Ref<RemotePlaybackAvailabilityCallback>&&, Ref<DeferredPromise>&&);
    void cancelWatchAvailability(std::optional<int32_t> id, Ref<DeferredPromise>&&);
    void prompt(Ref<DeferredPromise>&&);

    bool hasAvailabilityCallbacks() const;
    void availabilityChanged(bool);
    void playbackTargetPickerWasDismissed();
    void shouldPlayToRemoteTargetChanged(bool);
    void isPlayingToRemoteTargetChanged(bool);

    enum class State {
        Connecting,
        Connected,
        Disconnected,
    };
    State state() const { return m_state; }

    void invalidate();

    using RefCounted::ref;
    using RefCounted::deref;

    void* opaqueRootConcurrently() const;
    Node* ownerNode() const;

private:
    explicit RemotePlayback(HTMLMediaElement&);

    void refEventTarget() final { ref(); }
    void derefEventTarget() final { deref(); }

    void setState(State);
    void establishConnection();
    void disconnect();

    // ActiveDOMObject.
    const char* activeDOMObjectName() const final;

    // EventTargetWithInlineData.
    EventTargetInterface eventTargetInterface() const final { return RemotePlaybackEventTargetInterfaceType; }
    ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }

    WeakPtr<HTMLMediaElement> m_mediaElement;
    uint32_t m_nextId { 0 };

    using CallbackMap = HashMap<int32_t, Ref<RemotePlaybackAvailabilityCallback>>;
    CallbackMap m_callbackMap;

    using PromiseVector = Vector<Ref<DeferredPromise>>;
    PromiseVector m_availabilityPromises;
    PromiseVector m_cancelAvailabilityPromises;
    PromiseVector m_promptPromises;
    State m_state { State::Disconnected };
    bool m_available { false };
};

}

#endif // ENABLE(WIRELESS_PLAYBACK_TARGET)

