/*
 * Copyright (C) 2014 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.
 */

#import "config.h"
#import "ProcessAssertion.h"

#if PLATFORM(IOS)

#import "AssertionServicesSPI.h"
#import "Logging.h"
#import <UIKit/UIApplication.h>
#import <wtf/HashSet.h>
#import <wtf/RunLoop.h>
#import <wtf/Vector.h>

#if !PLATFORM(IOS_SIMULATOR)

using WebKit::ProcessAssertionClient;

@interface WKProcessAssertionBackgroundTaskManager : NSObject

+ (WKProcessAssertionBackgroundTaskManager *)shared;

- (void)incrementNeedsToRunInBackgroundCount;
- (void)decrementNeedsToRunInBackgroundCount;

- (void)addClient:(ProcessAssertionClient&)client;
- (void)removeClient:(ProcessAssertionClient&)client;

@end

@implementation WKProcessAssertionBackgroundTaskManager
{
    unsigned _needsToRunInBackgroundCount;
    UIBackgroundTaskIdentifier _backgroundTask;
    HashSet<ProcessAssertionClient*> _clients;
}

+ (WKProcessAssertionBackgroundTaskManager *)shared
{
    static WKProcessAssertionBackgroundTaskManager *shared = [WKProcessAssertionBackgroundTaskManager new];
    return shared;
}

- (instancetype)init
{
    self = [super init];
    if (!self)
        return nil;

    _backgroundTask = UIBackgroundTaskInvalid;

    return self;
}

- (void)dealloc
{
    if (_backgroundTask != UIBackgroundTaskInvalid)
        [[UIApplication sharedApplication] endBackgroundTask:_backgroundTask];

    [super dealloc];
}

- (void)addClient:(ProcessAssertionClient&)client
{
    _clients.add(&client);
}

- (void)removeClient:(ProcessAssertionClient&)client
{
    _clients.remove(&client);
}

- (void)_notifyClientsOfImminentSuspension
{
    ASSERT(RunLoop::isMain());

    for (auto* client : copyToVector(_clients))
        client->assertionWillExpireImminently();
}

- (void)_updateBackgroundTask
{
    if (_needsToRunInBackgroundCount && _backgroundTask == UIBackgroundTaskInvalid) {
        RELEASE_LOG(ProcessSuspension, "%p - WKProcessAssertionBackgroundTaskManager - beginBackgroundTaskWithName", self);
        _backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"com.apple.WebKit.ProcessAssertion" expirationHandler:^{
            RELEASE_LOG_ERROR(ProcessSuspension, "Background task expired while holding WebKit ProcessAssertion (isMainThread? %d).", RunLoop::isMain());
            // The expiration handler gets called on a non-main thread when the underlying assertion could not be taken (rdar://problem/27278419).
            if (RunLoop::isMain())
                [self _notifyClientsOfImminentSuspension];
            else {
                dispatch_sync(dispatch_get_main_queue(), ^{
                    [self _notifyClientsOfImminentSuspension];
                });
            }
            [[UIApplication sharedApplication] endBackgroundTask:_backgroundTask];
            _backgroundTask = UIBackgroundTaskInvalid;
        }];
    }

    if (!_needsToRunInBackgroundCount && _backgroundTask != UIBackgroundTaskInvalid) {
        RELEASE_LOG(ProcessSuspension, "%p - WKProcessAssertionBackgroundTaskManager - endBackgroundTask", self);
        [[UIApplication sharedApplication] endBackgroundTask:_backgroundTask];
        _backgroundTask = UIBackgroundTaskInvalid;
    }
}

- (void)incrementNeedsToRunInBackgroundCount
{
    ++_needsToRunInBackgroundCount;
    [self _updateBackgroundTask];
}

- (void)decrementNeedsToRunInBackgroundCount
{
    --_needsToRunInBackgroundCount;
    [self _updateBackgroundTask];
}

@end

namespace WebKit {

const BKSProcessAssertionFlags suspendedTabFlags = (BKSProcessAssertionAllowIdleSleep);
const BKSProcessAssertionFlags backgroundTabFlags = (BKSProcessAssertionAllowIdleSleep | BKSProcessAssertionPreventTaskSuspend);
const BKSProcessAssertionFlags foregroundTabFlags = (BKSProcessAssertionAllowIdleSleep | BKSProcessAssertionPreventTaskSuspend | BKSProcessAssertionWantsForegroundResourcePriority | BKSProcessAssertionPreventTaskThrottleDown);

static BKSProcessAssertionFlags flagsForState(AssertionState assertionState)
{
    switch (assertionState) {
    case AssertionState::Suspended:
        return suspendedTabFlags;
    case AssertionState::Background:
        return backgroundTabFlags;
    case AssertionState::Foreground:
        return foregroundTabFlags;
    }
}

ProcessAssertion::ProcessAssertion(pid_t pid, AssertionState assertionState, Function<void()>&& invalidationCallback)
    : m_invalidationCallback(WTFMove(invalidationCallback))
    , m_assertionState(assertionState)
{
    auto weakThis = createWeakPtr();
    BKSProcessAssertionAcquisitionHandler handler = ^(BOOL acquired) {
        if (!acquired) {
            RELEASE_LOG_ERROR(ProcessSuspension, " %p - ProcessAssertion() Unable to acquire assertion for process with PID %d", this, pid);
            ASSERT_NOT_REACHED();
            dispatch_async(dispatch_get_main_queue(), ^{
                if (weakThis)
                    markAsInvalidated();
            });
        }
    };
    RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion() Acquiring assertion for process with PID %d", this, pid);
    m_assertion = adoptNS([[BKSProcessAssertion alloc] initWithPID:pid flags:flagsForState(assertionState) reason:BKSProcessAssertionReasonExtension name:@"Web content visible" withHandler:handler]);
    m_assertion.get().invalidationHandler = ^() {
        dispatch_async(dispatch_get_main_queue(), ^{
            RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion() Process assertion for process with PID %d was invalidated", this, pid);
            if (weakThis)
                markAsInvalidated();
        });
    };
}

ProcessAssertion::~ProcessAssertion()
{
    m_assertion.get().invalidationHandler = nil;

    if (ProcessAssertionClient* client = this->client())
        [[WKProcessAssertionBackgroundTaskManager shared] removeClient:*client];

    RELEASE_LOG(ProcessSuspension, "%p - ~ProcessAssertion() Releasing process assertion", this);
    [m_assertion invalidate];
}

void ProcessAssertion::markAsInvalidated()
{
    ASSERT(RunLoop::isMain());

    m_validity = Validity::No;
    if (m_invalidationCallback)
        m_invalidationCallback();
}

void ProcessAssertion::setState(AssertionState assertionState)
{
    if (m_assertionState == assertionState)
        return;

    RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion::setState(%u)", this, static_cast<unsigned>(assertionState));
    m_assertionState = assertionState;
    [m_assertion setFlags:flagsForState(assertionState)];
}

void ProcessAndUIAssertion::updateRunInBackgroundCount()
{
    bool shouldHoldBackgroundAssertion = validity() != Validity::No && state() != AssertionState::Suspended;

    if (shouldHoldBackgroundAssertion) {
        if (!m_isHoldingBackgroundAssertion)
            [[WKProcessAssertionBackgroundTaskManager shared] incrementNeedsToRunInBackgroundCount];
    } else {
        if (m_isHoldingBackgroundAssertion)
            [[WKProcessAssertionBackgroundTaskManager shared] decrementNeedsToRunInBackgroundCount];
    }

    m_isHoldingBackgroundAssertion = shouldHoldBackgroundAssertion;
}

ProcessAndUIAssertion::ProcessAndUIAssertion(pid_t pid, AssertionState assertionState)
    : ProcessAssertion(pid, assertionState, [this] { updateRunInBackgroundCount(); })
{
    updateRunInBackgroundCount();
}

ProcessAndUIAssertion::~ProcessAndUIAssertion()
{
    if (m_isHoldingBackgroundAssertion)
        [[WKProcessAssertionBackgroundTaskManager shared] decrementNeedsToRunInBackgroundCount];
}

void ProcessAndUIAssertion::setState(AssertionState assertionState)
{
    ProcessAssertion::setState(assertionState);
    updateRunInBackgroundCount();
}

void ProcessAndUIAssertion::setClient(ProcessAssertionClient& newClient)
{
    [[WKProcessAssertionBackgroundTaskManager shared] addClient:newClient];
    if (ProcessAssertionClient* oldClient = this->client())
        [[WKProcessAssertionBackgroundTaskManager shared] removeClient:*oldClient];
    ProcessAssertion::setClient(newClient);
}

} // namespace WebKit

#else // PLATFORM(IOS_SIMULATOR)

namespace WebKit {

ProcessAssertion::ProcessAssertion(pid_t, AssertionState assertionState, Function<void()>&&)
    : m_assertionState(assertionState)
{
}

ProcessAssertion::~ProcessAssertion()
{
}

void ProcessAssertion::setState(AssertionState assertionState)
{
    m_assertionState = assertionState;
}

ProcessAndUIAssertion::ProcessAndUIAssertion(pid_t pid, AssertionState assertionState)
    : ProcessAssertion(pid, assertionState)
{
}

ProcessAndUIAssertion::~ProcessAndUIAssertion()
{
}

void ProcessAndUIAssertion::setState(AssertionState assertionState)
{
    ProcessAssertion::setState(assertionState);
}

void ProcessAndUIAssertion::setClient(ProcessAssertionClient& newClient)
{
    ProcessAssertion::setClient(newClient);
}

} // namespace WebKit

#endif // PLATFORM(IOS_SIMULATOR)

#endif // PLATFORM(IOS)
