/*
 * Copyright (C) 2009 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.
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "PixelDumpSupport.h"

#include "CyclicRedundancyCheck.h"
#include "DumpRenderTree.h"
#include "TestRunner.h"
#include <cstdio>
#include <wtf/Assertions.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>

#if USE(CG)
#include "PixelDumpSupportCG.h"
#elif USE(CAIRO)
#include "PixelDumpSupportCairo.h"
#elif USE(DIRECT2D)
#include "PixelDumpSupportDirect2D.h"
#endif

void dumpWebViewAsPixelsAndCompareWithExpected(const std::string& expectedHash)
{
    RefPtr<BitmapContext> context;
#if PLATFORM(MAC)
    if (gTestRunner->isPrinting())
        context = createPagedBitmapContext();
    else
#endif
        context = createBitmapContextFromWebView(gTestRunner->testOnscreen(), gTestRunner->testRepaint(), gTestRunner->testRepaintSweepHorizontally(), gTestRunner->dumpSelectionRect());
    ASSERT(context);
    
    // Compute the hash of the bitmap context pixels
    char actualHash[33];
    computeSHA1HashStringForBitmapContext(context.get(), actualHash);
    fprintf(testResult, "\nActualHash: %s\n", actualHash); // FIXME: No need for the leading newline.

    // Check the computed hash against the expected one and dump image on mismatch
    bool dumpImage = true;
    if (expectedHash.length() > 0) {
        ASSERT(expectedHash.length() == 32);

        fprintf(testResult, "\nExpectedHash: %s\n", expectedHash.c_str()); // FIXME: No need for the leading newline.
        
        if (expectedHash == actualHash) // FIXME: do case insensitive compare
            dumpImage = false;
    }

    if (dumpImage)
        dumpBitmap(context.get(), actualHash);
}

static void appendIntToVector(unsigned number, Vector<unsigned char>& vector)
{
    size_t offset = vector.size();
    vector.grow(offset + 4);
    vector[offset] = ((number >> 24) & 0xff);
    vector[offset + 1] = ((number >> 16) & 0xff);
    vector[offset + 2] = ((number >> 8) & 0xff);
    vector[offset + 3] = (number & 0xff);
}

static void convertChecksumToPNGComment(const char* checksum, Vector<unsigned char>& bytesToAdd)
{
    // Chunks of PNG files are <length>, <type>, <data>, <crc>.
    static const char textCommentPrefix[] = "\x00\x00\x00\x29tEXtchecksum\x00";
    static const size_t prefixLength = sizeof(textCommentPrefix) - 1; // The -1 is for the null at the end of the char[].
    static const size_t checksumLength = 32;

    bytesToAdd.append(textCommentPrefix, prefixLength);
    bytesToAdd.append(checksum, checksumLength);

    Vector<unsigned char> dataToCrc;
    dataToCrc.append(textCommentPrefix + 4, prefixLength - 4); // Don't include the chunk length in the crc.
    dataToCrc.append(checksum, checksumLength);
    unsigned crc32 = computeCrc(dataToCrc);

    appendIntToVector(crc32, bytesToAdd);
}

static size_t offsetAfterIHDRChunk(const unsigned char* data, const size_t dataLength)
{
    const int pngHeaderLength = 8;
    const int pngIHDRChunkLength = 25; // chunk length + "IHDR" + 13 bytes of data + checksum
    return pngHeaderLength + pngIHDRChunkLength;
}

void printPNG(const unsigned char* data, const size_t dataLength, const char* checksum)
{
    Vector<unsigned char> bytesToAdd;
    convertChecksumToPNGComment(checksum, bytesToAdd);

    fprintf(testResult, "Content-Type: image/png\n");
    fprintf(testResult, "Content-Length: %lu\n", static_cast<unsigned long>(dataLength + bytesToAdd.size()));

    size_t insertOffset = offsetAfterIHDRChunk(data, dataLength);

    fwrite(data, 1, insertOffset, testResult);
    fwrite(bytesToAdd.data(), 1, bytesToAdd.size(), testResult);

    const size_t bytesToWriteInOneChunk = 1 << 15;
    data += insertOffset;
    size_t dataRemainingToWrite = dataLength - insertOffset;
    while (dataRemainingToWrite) {
        size_t bytesToWriteInThisChunk = std::min(dataRemainingToWrite, bytesToWriteInOneChunk);
        size_t bytesWritten = fwrite(data, 1, bytesToWriteInThisChunk, testResult);
        if (bytesWritten != bytesToWriteInThisChunk)
            break;
        dataRemainingToWrite -= bytesWritten;
        data += bytesWritten;
    }
}
