/*
* Copyright (C) 2020 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 "ShareDataReader.h"

#include "BlobLoader.h"
#include "Document.h"
#include "SharedBuffer.h"

namespace WebCore {

ShareDataReader::ShareDataReader(CompletionHandler<void(ExceptionOr<ShareDataWithParsedURL&>)>&& completionHandler)
    : m_completionHandler(WTFMove(completionHandler))
{

}

ShareDataReader::~ShareDataReader()
{
    cancel();
}

void ShareDataReader::start(Document* document, ShareDataWithParsedURL&& shareData)
{
    m_filesReadSoFar = 0;
    m_shareData = WTFMove(shareData);
    int count = 0;
    m_pendingFileLoads.reserveInitialCapacity(m_shareData.shareData.files.size());
    for (auto& blob : m_shareData.shareData.files) {
        m_pendingFileLoads.uncheckedAppend(makeUniqueRef<BlobLoader>([this, count, fileName = blob->name()](BlobLoader&) {
            this->didFinishLoading(count, fileName);
        }));
        m_pendingFileLoads.last()->start(*blob, document, FileReaderLoader::ReadAsArrayBuffer);
        ++count;
    }
}

void ShareDataReader::didFinishLoading(int loadIndex, const String& fileName)
{
    if (m_pendingFileLoads.isEmpty()) {
        // cancel() was called.
        return;
    }

    if (m_pendingFileLoads[loadIndex]->errorCode()) {
        if (auto completionHandler = std::exchange(m_completionHandler, { }))
            completionHandler(Exception { AbortError, "Abort due to error while reading files."_s });
        cancel();
        return;
    }

    auto arrayBuffer = m_pendingFileLoads[loadIndex]->arrayBufferResult();

    RawFile file;
    file.fileName = fileName;
    file.fileData = SharedBuffer::create(static_cast<const unsigned char*>(arrayBuffer->data()), arrayBuffer->byteLength());
    m_shareData.files.append(WTFMove(file));
    m_filesReadSoFar++;

    if (m_filesReadSoFar == static_cast<int>(m_pendingFileLoads.size())) {
        m_pendingFileLoads.clear();
        if (auto completionHandler = std::exchange(m_completionHandler, { }))
            completionHandler(m_shareData);
    }
}

void ShareDataReader::cancel()
{
    // Don't call m_pendingFileLoads.clear() here since destroying a BlobLoader will cause its completion handler
    // to get called, which will call didFinishLoading() and try to access m_pendingFileLoads.
    std::exchange(m_pendingFileLoads, { });
}

}
