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

#include "config.h"
#include "APIUserContentExtensionStore.h"

#if ENABLE(CONTENT_EXTENSIONS)

#include "APIUserContentExtension.h"
#include "NetworkCacheData.h"
#include "NetworkCacheDecoder.h"
#include "NetworkCacheEncoder.h"
#include "NetworkCacheFileSystem.h"
#include "SharedMemory.h"
#include "WebCompiledContentExtension.h"
#include <WebCore/ContentExtensionCompiler.h>
#include <WebCore/ContentExtensionError.h>
#include <string>
#include <wtf/NeverDestroyed.h>
#include <wtf/RunLoop.h>
#include <wtf/WorkQueue.h>

using namespace WebKit::NetworkCache;

namespace API {

UserContentExtensionStore& UserContentExtensionStore::defaultStore()
{
    static UserContentExtensionStore* defaultStore = adoptRef(new UserContentExtensionStore).leakRef();
    return *defaultStore;
}

Ref<UserContentExtensionStore> UserContentExtensionStore::storeWithPath(const WTF::String& storePath)
{
    return adoptRef(*new UserContentExtensionStore(storePath));
}

UserContentExtensionStore::UserContentExtensionStore()
    : UserContentExtensionStore(defaultStorePath())
{
}

UserContentExtensionStore::UserContentExtensionStore(const WTF::String& storePath)
    : m_storePath(storePath)
    , m_compileQueue(WorkQueue::create("UserContentExtensionStore Compile Queue", WorkQueue::Type::Concurrent))
    , m_readQueue(WorkQueue::create("UserContentExtensionStore Read Queue"))
    , m_removeQueue(WorkQueue::create("UserContentExtensionStore Remove Queue"))
{
}

UserContentExtensionStore::~UserContentExtensionStore()
{
}

static String constructedPath(const String& base, const String& identifier)
{
    return WebCore::pathByAppendingComponent(base, "ContentExtension-" + WebCore::encodeForFileName(identifier));
}

const size_t ContentExtensionFileHeaderSize = sizeof(uint32_t) + 4 * sizeof(uint64_t);
struct ContentExtensionMetaData {
    uint32_t version { UserContentExtensionStore::CurrentContentExtensionFileVersion };
    uint64_t actionsSize { 0 };
    uint64_t filtersWithoutDomainsBytecodeSize { 0 };
    uint64_t filtersWithDomainBytecodeSize { 0 };
    uint64_t domainFiltersBytecodeSize { 0 };
    
    size_t fileSize() const
    {
        return ContentExtensionFileHeaderSize
            + actionsSize
            + filtersWithoutDomainsBytecodeSize
            + filtersWithDomainBytecodeSize
            + domainFiltersBytecodeSize;
    }
};

static Data encodeContentExtensionMetaData(const ContentExtensionMetaData& metaData)
{
    WebKit::NetworkCache::Encoder encoder;

    encoder << metaData.version;
    encoder << metaData.actionsSize;
    encoder << metaData.filtersWithoutDomainsBytecodeSize;
    encoder << metaData.filtersWithDomainBytecodeSize;
    encoder << metaData.domainFiltersBytecodeSize;

    ASSERT(encoder.bufferSize() == ContentExtensionFileHeaderSize);
    return Data(encoder.buffer(), encoder.bufferSize());
}

static bool decodeContentExtensionMetaData(ContentExtensionMetaData& metaData, const Data& fileData)
{
    bool success = false;
    fileData.apply([&metaData, &success, &fileData](const uint8_t* data, size_t size) {
        // The file data should be mapped into one continuous memory segment so the size
        // passed to the applier should always equal the data size.
        if (size != fileData.size())
            return false;

        WebKit::NetworkCache::Decoder decoder(data, size);
        if (!decoder.decode(metaData.version))
            return false;
        if (!decoder.decode(metaData.actionsSize))
            return false;
        if (!decoder.decode(metaData.filtersWithoutDomainsBytecodeSize))
            return false;
        if (!decoder.decode(metaData.filtersWithDomainBytecodeSize))
            return false;
        if (!decoder.decode(metaData.domainFiltersBytecodeSize))
            return false;
        success = true;
        return false;
    });
    return success;
}

static bool openAndMapContentExtension(const String& path, ContentExtensionMetaData& metaData, Data& fileData)
{
    fileData = mapFile(WebCore::fileSystemRepresentation(path).data());
    if (fileData.isNull())
        return false;

    if (!decodeContentExtensionMetaData(metaData, fileData))
        return false;

    return true;
}

static bool writeDataToFile(const Data& fileData, WebCore::PlatformFileHandle fd)
{
    bool success = true;
    fileData.apply([fd, &success](const uint8_t* data, size_t size) {
        if (WebCore::writeToFile(fd, (const char*)data, size) == -1) {
            success = false;
            return false;
        }
        return true;
    });
    
    return success;
}

static std::error_code compiledToFile(String&& json, const String& finalFilePath, ContentExtensionMetaData& metaData, Data& mappedData)
{
    using namespace WebCore::ContentExtensions;

    class CompilationClient final : public ContentExtensionCompilationClient {
    public:
        CompilationClient(WebCore::PlatformFileHandle fileHandle, ContentExtensionMetaData& metaData)
            : m_fileHandle(fileHandle)
            , m_metaData(metaData)
        {
            ASSERT(!metaData.actionsSize);
            ASSERT(!metaData.filtersWithoutDomainsBytecodeSize);
            ASSERT(!metaData.filtersWithDomainBytecodeSize);
            ASSERT(!metaData.domainFiltersBytecodeSize);
        }
        
        void writeFiltersWithoutDomainsBytecode(Vector<DFABytecode>&& bytecode) override
        {
            ASSERT(!m_filtersWithDomainBytecodeWritten);
            ASSERT(!m_domainFiltersBytecodeWritten);
            m_filtersWithoutDomainsBytecodeWritten += bytecode.size();
            writeToFile(Data(bytecode.data(), bytecode.size()));
        }
        
        void writeFiltersWithDomainsBytecode(Vector<DFABytecode>&& bytecode) override
        {
            ASSERT(!m_domainFiltersBytecodeWritten);
            m_filtersWithDomainBytecodeWritten += bytecode.size();
            writeToFile(Data(bytecode.data(), bytecode.size()));
        }
        
        void writeDomainFiltersBytecode(Vector<DFABytecode>&& bytecode) override
        {
            m_domainFiltersBytecodeWritten += bytecode.size();
            writeToFile(Data(bytecode.data(), bytecode.size()));
        }

        void writeActions(Vector<SerializedActionByte>&& actions) override
        {
            ASSERT(!m_filtersWithoutDomainsBytecodeWritten);
            ASSERT(!m_filtersWithDomainBytecodeWritten);
            ASSERT(!m_domainFiltersBytecodeWritten);
            ASSERT(!m_actionsWritten);
            m_actionsWritten += actions.size();
            writeToFile(Data(actions.data(), actions.size()));
        }
        
        void finalize() override
        {
            m_metaData.actionsSize = m_actionsWritten;
            m_metaData.filtersWithoutDomainsBytecodeSize = m_filtersWithoutDomainsBytecodeWritten;
            m_metaData.filtersWithDomainBytecodeSize = m_filtersWithDomainBytecodeWritten;
            m_metaData.domainFiltersBytecodeSize = m_domainFiltersBytecodeWritten;
            
            Data header = encodeContentExtensionMetaData(m_metaData);
            if (!m_fileError && WebCore::seekFile(m_fileHandle, 0ll, WebCore::FileSeekOrigin::SeekFromBeginning) == -1) {
                WebCore::closeFile(m_fileHandle);
                m_fileError = true;
            }
            writeToFile(header);
        }
        
        bool hadErrorWhileWritingToFile() { return m_fileError; }

    private:
        void writeToFile(const Data& data)
        {
            if (!m_fileError && !writeDataToFile(data, m_fileHandle)) {
                WebCore::closeFile(m_fileHandle);
                m_fileError = true;
            }
        }
        
        WebCore::PlatformFileHandle m_fileHandle;
        ContentExtensionMetaData& m_metaData;
        size_t m_filtersWithoutDomainsBytecodeWritten { 0 };
        size_t m_filtersWithDomainBytecodeWritten { 0 };
        size_t m_domainFiltersBytecodeWritten { 0 };
        size_t m_actionsWritten { 0 };
        bool m_fileError { false };
    };

    auto temporaryFileHandle = WebCore::invalidPlatformFileHandle;
    String temporaryFilePath = WebCore::openTemporaryFile("ContentExtension", temporaryFileHandle);
    if (temporaryFileHandle == WebCore::invalidPlatformFileHandle)
        return UserContentExtensionStore::Error::CompileFailed;
    
    char invalidHeader[ContentExtensionFileHeaderSize];
    memset(invalidHeader, 0xFF, sizeof(invalidHeader));
    // This header will be rewritten in CompilationClient::finalize.
    if (WebCore::writeToFile(temporaryFileHandle, invalidHeader, sizeof(invalidHeader)) == -1) {
        WebCore::closeFile(temporaryFileHandle);
        return UserContentExtensionStore::Error::CompileFailed;
    }

    CompilationClient compilationClient(temporaryFileHandle, metaData);
    
    if (auto compilerError = compileRuleList(compilationClient, WTFMove(json))) {
        WebCore::closeFile(temporaryFileHandle);
        return compilerError;
    }
    if (compilationClient.hadErrorWhileWritingToFile()) {
        WebCore::closeFile(temporaryFileHandle);
        return UserContentExtensionStore::Error::CompileFailed;
    }
    
    mappedData = adoptAndMapFile(temporaryFileHandle, 0, metaData.fileSize());
    if (mappedData.isNull())
        return UserContentExtensionStore::Error::CompileFailed;

    if (!WebCore::moveFile(temporaryFilePath, finalFilePath))
        return UserContentExtensionStore::Error::CompileFailed;

    return { };
}

static RefPtr<API::UserContentExtension> createExtension(const String& identifier, const ContentExtensionMetaData& metaData, const Data& fileData)
{
    auto sharedMemory = WebKit::SharedMemory::create(const_cast<uint8_t*>(fileData.data()), fileData.size(), WebKit::SharedMemory::Protection::ReadOnly);
    auto compiledContentExtensionData = WebKit::WebCompiledContentExtensionData(
        WTFMove(sharedMemory),
        fileData,
        ContentExtensionFileHeaderSize,
        metaData.actionsSize,
        ContentExtensionFileHeaderSize
            + metaData.actionsSize,
        metaData.filtersWithoutDomainsBytecodeSize,
        ContentExtensionFileHeaderSize
            + metaData.actionsSize
            + metaData.filtersWithoutDomainsBytecodeSize,
        metaData.filtersWithDomainBytecodeSize,
        ContentExtensionFileHeaderSize
            + metaData.actionsSize
            + metaData.filtersWithoutDomainsBytecodeSize
            + metaData.filtersWithDomainBytecodeSize,
        metaData.domainFiltersBytecodeSize
    );
    auto compiledContentExtension = WebKit::WebCompiledContentExtension::create(WTFMove(compiledContentExtensionData));
    return API::UserContentExtension::create(identifier, WTFMove(compiledContentExtension));
}

void UserContentExtensionStore::lookupContentExtension(const WTF::String& identifier, std::function<void(RefPtr<API::UserContentExtension>, std::error_code)> completionHandler)
{
    m_readQueue->dispatch([protectedThis = makeRef(*this), identifier = identifier.isolatedCopy(), storePath = m_storePath.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
        auto path = constructedPath(storePath, identifier);
        
        ContentExtensionMetaData metaData;
        Data fileData;
        if (!openAndMapContentExtension(path, metaData, fileData)) {
            RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)] {
                completionHandler(nullptr, Error::LookupFailed);
            });
            return;
        }
        
        if (metaData.version != UserContentExtensionStore::CurrentContentExtensionFileVersion) {
            RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)] {
                completionHandler(nullptr, Error::VersionMismatch);
            });
            return;
        }
        
        RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), identifier = WTFMove(identifier), fileData = WTFMove(fileData), metaData = WTFMove(metaData), completionHandler = WTFMove(completionHandler)] {
            RefPtr<API::UserContentExtension> userContentExtension = createExtension(identifier, metaData, fileData);
            completionHandler(userContentExtension, { });
        });
    });
}

void UserContentExtensionStore::compileContentExtension(const WTF::String& identifier, WTF::String&& json, std::function<void(RefPtr<API::UserContentExtension>, std::error_code)> completionHandler)
{
    m_compileQueue->dispatch([protectedThis = makeRef(*this), identifier = identifier.isolatedCopy(), json = json.isolatedCopy(), storePath = m_storePath.isolatedCopy(), completionHandler = WTFMove(completionHandler)] () mutable {
        auto path = constructedPath(storePath, identifier);

        ContentExtensionMetaData metaData;
        Data fileData;
        auto error = compiledToFile(WTFMove(json), path, metaData, fileData);
        if (error) {
            RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), error = WTFMove(error), completionHandler = WTFMove(completionHandler)] {
                completionHandler(nullptr, error);
            });
            return;
        }

        RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), identifier = WTFMove(identifier), fileData = WTFMove(fileData), metaData = WTFMove(metaData), completionHandler = WTFMove(completionHandler)] {
            RefPtr<API::UserContentExtension> userContentExtension = createExtension(identifier, metaData, fileData);
            completionHandler(userContentExtension, { });
        });
    });
}

void UserContentExtensionStore::removeContentExtension(const WTF::String& identifier, std::function<void(std::error_code)> completionHandler)
{
    m_removeQueue->dispatch([protectedThis = makeRef(*this), identifier = identifier.isolatedCopy(), storePath = m_storePath.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
        auto path = constructedPath(storePath, identifier);

        if (!WebCore::deleteFile(path)) {
            RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)] {
                completionHandler(Error::RemoveFailed);
            });
            return;
        }

        RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)] {
            completionHandler({ });
        });
    });
}

void UserContentExtensionStore::synchronousRemoveAllContentExtensions()
{
    for (const auto& path : WebCore::listDirectory(m_storePath, "*"))
        WebCore::deleteFile(path);
}

void UserContentExtensionStore::invalidateContentExtensionVersion(const WTF::String& identifier)
{
    auto file = WebCore::openFile(constructedPath(m_storePath, identifier), WebCore::OpenForWrite);
    if (file == WebCore::invalidPlatformFileHandle)
        return;
    ContentExtensionMetaData invalidHeader = {0, 0, 0, 0, 0};
    auto bytesWritten = WebCore::writeToFile(file, reinterpret_cast<const char*>(&invalidHeader), sizeof(invalidHeader));
    ASSERT_UNUSED(bytesWritten, bytesWritten == sizeof(invalidHeader));
    WebCore::closeFile(file);
}
    
const std::error_category& userContentExtensionStoreErrorCategory()
{
    class UserContentExtensionStoreErrorCategory : public std::error_category {
        const char* name() const noexcept override
        {
            return "user content extension store";
        }

        std::string message(int errorCode) const override
        {
            switch (static_cast<UserContentExtensionStore::Error>(errorCode)) {
            case UserContentExtensionStore::Error::LookupFailed:
                return "Unspecified error during lookup.";
            case UserContentExtensionStore::Error::VersionMismatch:
                return "Version of file does not match version of interpreter.";
            case UserContentExtensionStore::Error::CompileFailed:
                return "Unspecified error during compile.";
            case UserContentExtensionStore::Error::RemoveFailed:
                return "Unspecified error during remove.";
            }

            return std::string();
        }
    };

    static NeverDestroyed<UserContentExtensionStoreErrorCategory> contentExtensionErrorCategory;
    return contentExtensionErrorCategory;
}

} // namespace API

#endif // ENABLE(CONTENT_EXTENSIONS)
