/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef image_expectations_DEFINED
#define image_expectations_DEFINED

#include "SkBitmap.h"
#include "SkJSONCPP.h"
#include "SkOSFile.h"
#include "SkRefCnt.h"

namespace sk_tools {

    /**
     * The digest of an image (either an image we have generated locally, or an image expectation).
     *
     * Currently, this is always a uint64_t hash digest of an SkBitmap.
     */
    class ImageDigest : public SkRefCnt {
    public:
        /**
         * Create an ImageDigest of a bitmap.
         *
         * Note that this is an expensive operation, because it has to examine all pixels in
         * the bitmap.  You may wish to consider using the BitmapAndDigest class, which will
         * compute the ImageDigest lazily.
         *
         * @param bitmap image to get the digest of
         */
        explicit ImageDigest(const SkBitmap &bitmap);

        /**
         * Create an ImageDigest using a hashType/hashValue pair.
         *
         * @param hashType the algorithm used to generate the hash; for now, only
         *     kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5 is allowed.
         * @param hashValue the value generated by the hash algorithm for a particular image.
         */
        explicit ImageDigest(const SkString &hashType, uint64_t hashValue);

        /**
         * Returns the hash digest type as an SkString.
         *
         * For now, this always returns kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5 .
         */
        SkString getHashType() const;

        /**
         * Returns the hash digest value as a uint64_t.
         */
        uint64_t getHashValue() const;

    private:
        uint64_t fHashValue;
    };

    /**
     * Container that holds a reference to an SkBitmap and computes its ImageDigest lazily.
     *
     * Computing the ImageDigest can be expensive, so this can help you postpone (or maybe even
     * avoid) that work.
     */
    class BitmapAndDigest {
    public:
        explicit BitmapAndDigest(const SkBitmap &bitmap);

        const ImageDigest *getImageDigestPtr();
        const SkBitmap *getBitmapPtr() const;
    private:
        const SkBitmap fBitmap;
        SkAutoTUnref<ImageDigest> fImageDigestRef;
    };

    /**
     * Collects ImageDigests of actually rendered images, perhaps comparing to expectations.
     */
    class ImageResultsAndExpectations {
    public:
        /**
         * Adds expectations from a JSON file, returning true if successful.
         *
         * If the file exists but is empty, it succeeds, and there will be no expectations.
         * If the file does not exist, this will fail.
         *
         * Reasoning:
         * Generating expectations the first time can be a tricky chicken-and-egg
         * proposition.  "I need actual results to turn into expectations... but the only
         * way to get actual results is to run the tool, and the tool won't run without
         * expectations!"
         * We could make the tool run even if there is no expectations file at all, but it's
         * better for the tool to fail if the expectations file is not found--that will tell us
         * quickly if files are not being copied around as they should be.
         * Creating an empty file is an easy way to break the chicken-and-egg cycle and generate
         * the first real expectations.
         */
        bool readExpectationsFile(const char *jsonPath);

        /**
         * Adds this image to the summary of results.
         *
         * @param sourceName name of the source file that generated this result
         * @param fileName relative path to the image output file on local disk
         * @param digest description of the image's contents
         * @param tileNumber if not NULL, pointer to tile number
         */
        void add(const char *sourceName, const char *fileName, const ImageDigest &digest,
                 const int *tileNumber=NULL);

        /**
         * Returns true if this test result matches its expectations.
         * If there are no expectations for this test result, this will return false.
         *
         * @param sourceName name of the source file that generated this result
         * @param digest description of the image's contents
         * @param tileNumber if not NULL, pointer to tile number
         */
        bool matchesExpectation(const char *sourceName, const ImageDigest &digest,
                                const int *tileNumber=NULL);

        /**
         * Writes the summary (as constructed so far) to a file.
         *
         * @param filename path to write the summary to
         */
        void writeToFile(const char *filename) const;

    private:

        /**
         * Read the file contents from filePtr and parse them into jsonRoot.
         *
         * It is up to the caller to close filePtr after this is done.
         *
         * Returns true if successful.
         */
        static bool Parse(SkFILE* filePtr, Json::Value *jsonRoot);

        Json::Value fActualResults;
        Json::Value fExpectedJsonRoot;
        Json::Value fExpectedResults;
    };

} // namespace sk_tools

#endif  // image_expectations_DEFINED
