/*
 * Copyright (C) 2016 Apple Inc. All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "config.h"
#include "UserMediaProcessManager.h"

#if ENABLE(MEDIA_STREAM)

#include "MediaDeviceSandboxExtensions.h"
#include "WebPageMessages.h"
#include "WebPageProxy.h"
#include "WebProcessProxy.h"
#include <wtf/HashMap.h>
#include <wtf/NeverDestroyed.h>

namespace WebKit {

static const char* const audioExtensionPath = "com.apple.webkit.microphone";
static const char* const videoExtensionPath = "com.apple.webkit.camera";

class ProcessState {
public:
    ProcessState() { }
    ProcessState(const ProcessState&) = delete;

    void addRequestManager(UserMediaPermissionRequestManagerProxy&);
    void removeRequestManager(UserMediaPermissionRequestManagerProxy&);
    Vector<UserMediaPermissionRequestManagerProxy*>& managers() { return m_managers; }

    enum SandboxExtensionsGranted {
        None = 0,
        Video = 1 << 0,
        Audio = 1 << 1
    };

    SandboxExtensionsGranted sandboxExtensionsGranted() { return m_pageSandboxExtensionsGranted; }
    void setSandboxExtensionsGranted(unsigned granted) { m_pageSandboxExtensionsGranted = static_cast<SandboxExtensionsGranted>(granted); }

private:
    Vector<UserMediaPermissionRequestManagerProxy*> m_managers;
    SandboxExtensionsGranted m_pageSandboxExtensionsGranted { SandboxExtensionsGranted::None };
};

static HashMap<WebProcessProxy*, std::unique_ptr<ProcessState>>& stateMap()
{
    static NeverDestroyed<HashMap<WebProcessProxy*, std::unique_ptr<ProcessState>>> map;
    return map;
}

static ProcessState& processState(WebProcessProxy& process)
{
    auto& state = stateMap().add(&process, nullptr).iterator->value;
    if (state)
        return *state;

    state = std::make_unique<ProcessState>();
    return *state;
}

void ProcessState::addRequestManager(UserMediaPermissionRequestManagerProxy& proxy)
{
    ASSERT(!m_managers.contains(&proxy));
    m_managers.append(&proxy);
}

void ProcessState::removeRequestManager(UserMediaPermissionRequestManagerProxy& proxy)
{
    ASSERT(m_managers.contains(&proxy));
    m_managers.removeFirstMatching([&proxy](auto other) {
        return other == &proxy;
    });
}

UserMediaProcessManager& UserMediaProcessManager::singleton()
{
    static NeverDestroyed<UserMediaProcessManager> manager;
    return manager;
}

void UserMediaProcessManager::addUserMediaPermissionRequestManagerProxy(UserMediaPermissionRequestManagerProxy& proxy)
{
    processState(proxy.page().process()).addRequestManager(proxy);
}

void UserMediaProcessManager::removeUserMediaPermissionRequestManagerProxy(UserMediaPermissionRequestManagerProxy& proxy)
{
    endedCaptureSession(proxy);

    auto& state = processState(proxy.page().process());
    state.removeRequestManager(proxy);
    if (state.managers().isEmpty()) {
        auto it = stateMap().find(&proxy.page().process());
        stateMap().remove(it);
    }
}

void UserMediaProcessManager::muteCaptureMediaStreamsExceptIn(WebPageProxy& pageStartingCapture)
{
#if PLATFORM(COCOA)
    for (auto& state : stateMap()) {
        for (auto& manager : state.value->managers()) {
            if (&manager->page() == &pageStartingCapture)
                continue;
            manager->page().setMuted(WebCore::MediaProducer::CaptureDevicesAreMuted);
        }
    }
#else
    UNUSED_PARAM(pageStartingCapture);
#endif
}

void UserMediaProcessManager::willCreateMediaStream(UserMediaPermissionRequestManagerProxy& proxy, bool withAudio, bool withVideo)
{
#if ENABLE(SANDBOX_EXTENSIONS)
    auto& processStartingCapture = proxy.page().process();

    ASSERT(stateMap().contains(&processStartingCapture));

    proxy.page().activateMediaStreamCaptureInPage();

    auto& state = processState(processStartingCapture);
    size_t extensionCount = 0;
    unsigned requiredExtensions = ProcessState::SandboxExtensionsGranted::None;

    if (withAudio) {
        requiredExtensions |= ProcessState::SandboxExtensionsGranted::Audio;
        extensionCount++;
    }
    if (withVideo) {
        requiredExtensions |= ProcessState::SandboxExtensionsGranted::Video;
        extensionCount++;
    }

    unsigned currentExtensions = state.sandboxExtensionsGranted();

#if ENABLE(WEB_RTC) && USE(LIBWEBRTC)
    if (currentExtensions == ProcessState::SandboxExtensionsGranted::None && (withAudio || withVideo))
        processStartingCapture.send(Messages::WebPage::DisableICECandidateFiltering(), proxy.page().pageID());
#endif

    if (!(requiredExtensions & currentExtensions)) {
        SandboxExtension::HandleArray handles;
        handles.allocate(extensionCount);

        Vector<String> ids;
        ids.reserveCapacity(extensionCount);

        if (withAudio && requiredExtensions & ProcessState::SandboxExtensionsGranted::Audio) {
            if (SandboxExtension::createHandleForGenericExtension(audioExtensionPath, handles[--extensionCount])) {
                ids.append(ASCIILiteral(audioExtensionPath));
                currentExtensions |= ProcessState::SandboxExtensionsGranted::Audio;
            }
        }

        if (withVideo && requiredExtensions & ProcessState::SandboxExtensionsGranted::Video) {
            if (SandboxExtension::createHandleForGenericExtension(videoExtensionPath, handles[--extensionCount])) {
                ids.append(ASCIILiteral(videoExtensionPath));
                currentExtensions |= ProcessState::SandboxExtensionsGranted::Video;
            }
        }

        state.setSandboxExtensionsGranted(currentExtensions);
        processStartingCapture.send(Messages::WebPage::GrantUserMediaDeviceSandboxExtensions(MediaDeviceSandboxExtensions(ids, WTFMove(handles))), proxy.page().pageID());
    }
#endif
}

void UserMediaProcessManager::startedCaptureSession(UserMediaPermissionRequestManagerProxy& proxy)
{
    ASSERT(stateMap().contains(&proxy.page().process()));
}

void UserMediaProcessManager::endedCaptureSession(UserMediaPermissionRequestManagerProxy& proxy)
{
#if ENABLE(SANDBOX_EXTENSIONS)
    ASSERT(stateMap().contains(&proxy.page().process()));

    auto& state = processState(proxy.page().process());
    bool hasAudioCapture = false;
    bool hasVideoCapture = false;
    for (auto& manager : state.managers()) {
        if (manager->page().hasActiveAudioStream())
            hasAudioCapture = true;
        if (manager->page().hasActiveVideoStream())
            hasVideoCapture = true;
    }

    if (hasAudioCapture && hasVideoCapture)
        return;

    Vector<String> params;
    unsigned currentExtensions = state.sandboxExtensionsGranted();
    if (!hasAudioCapture && currentExtensions & ProcessState::SandboxExtensionsGranted::Audio) {
        params.append(ASCIILiteral(audioExtensionPath));
        currentExtensions &= ~ProcessState::SandboxExtensionsGranted::Audio;
    }
    if (!hasVideoCapture && currentExtensions & ProcessState::SandboxExtensionsGranted::Video) {
        params.append(ASCIILiteral(videoExtensionPath));
        currentExtensions &= ~ProcessState::SandboxExtensionsGranted::Video;
    }

    if (params.isEmpty())
        return;

#if ENABLE(WEB_RTC) && USE(LIBWEBRTC)
    // FIXME: We should only do EnableICECandidateFiltering when the page is being reloaded.
    if (currentExtensions == ProcessState::SandboxExtensionsGranted::None)
        proxy.page().process().send(Messages::WebPage::EnableICECandidateFiltering(), proxy.page().pageID());
#endif

    state.setSandboxExtensionsGranted(currentExtensions);
    proxy.page().process().send(Messages::WebPage::RevokeUserMediaDeviceSandboxExtensions(params), proxy.page().pageID());
#endif
}

void UserMediaProcessManager::setCaptureEnabled(bool enabled)
{
    if (enabled == m_captureEnabled)
        return;

    m_captureEnabled = enabled;

    if (enabled)
        return;

    for (auto& state : stateMap()) {
        for (auto& manager : state.value->managers())
            manager->stopCapture();
    }
}

} // namespace WebKit

#endif
