/*
 * 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);

        /**
         * Adds a key/value pair to the descriptions dict within the summary of results.
         *
         * @param key key within the descriptions dict
         * @param value value to associate with that key
         */
        void addDescription(const char *key, const char *value);

        /**
         * 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 fDescriptions;
        Json::Value fExpectedJsonRoot;
        Json::Value fExpectedResults;
    };

} // namespace sk_tools

#endif  // image_expectations_DEFINED
