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

#ifndef skqp_DEFINED
#define skqp_DEFINED

#include <cstdint>
#include <memory>
#include <string>
#include <tuple>
#include <unordered_set>
#include <unordered_map>
#include <vector>

class SkData;
template <typename T> class sk_sp;

namespace skiagm {
class GM;
}

namespace skiatest {
struct Test;
}

class SkStreamAsset;

////////////////////////////////////////////////////////////////////////////////
class SkQPAssetManager {
public:
    SkQPAssetManager() {}
    virtual ~SkQPAssetManager() {}
    virtual sk_sp<SkData> open(const char* path) = 0;
private:
    SkQPAssetManager(const SkQPAssetManager&) = delete;
    SkQPAssetManager& operator=(const SkQPAssetManager&) = delete;
};

class SkQP {
public:
    enum class SkiaBackend {
        kGL,
        kGLES,
        kVulkan,
    };
    using GMFactory = skiagm::GM* (*)(void*);
    using UnitTest = const skiatest::Test*;

    ////////////////////////////////////////////////////////////////////////////

    /** These functions provide a descriptive name for the given value.*/
    static std::string GetGMName(GMFactory);
    static const char* GetUnitTestName(UnitTest);
    static const char* GetBackendName(SkiaBackend);

    SkQP();
    ~SkQP();

    /**
        Initialize Skia and the SkQP.  Should be executed only once.

        @param assetManager - provides assets for the models.  Does not take ownership.
        @param reportDirectory - where to write out report.
    */
    void init(SkQPAssetManager* assetManager, const char* reportDirectory);

    struct RenderOutcome {
        // All three values will be 0 if the test passes.
        int fMaxError = 0;        // maximum error of all pixel.
        int fBadPixelCount = 0;   // number of pixels with non-zero error.
        int64_t fTotalError = 0;  // sum of error for all bad pixels.
    };

    /**
        @return render outcome and error string.  Only errors running or
                evaluating the GM will result in a non-empty error string.
    */
    std::tuple<RenderOutcome, std::string> evaluateGM(SkiaBackend, GMFactory);

    /** @return a (hopefully empty) list of errors produced by this unit test.  */
    std::vector<std::string> executeTest(UnitTest);

    /** Call this after running all checks to write a report into the given
        report directory. */
    void makeReport();

    /** @return a list of backends that this version of SkQP supports.  */
    const std::vector<SkiaBackend>& getSupportedBackends() const { return fSupportedBackends; }
    /** @return a list of all Skia GMs in lexicographic order.  */
    const std::vector<GMFactory>& getGMs() const { return fGMs; }
    /** @return a list of all Skia GPU unit tests in lexicographic order.  */
    const std::vector<UnitTest>& getUnitTests() const { return fUnitTests; }
    ////////////////////////////////////////////////////////////////////////////

private:
    struct RenderResult {
        SkiaBackend fBackend;
        GMFactory fGM;
        RenderOutcome fOutcome;
   };
    struct UnitTestResult {
        UnitTest fUnitTest;
        std::vector<std::string> fErrors;
    };
    std::vector<RenderResult> fRenderResults;
    std::vector<UnitTestResult> fUnitTestResults;
    std::vector<SkiaBackend> fSupportedBackends;
    SkQPAssetManager* fAssetManager = nullptr;
    std::string fReportDirectory;
    std::vector<UnitTest> fUnitTests;
    std::vector<GMFactory> fGMs;
    std::unordered_map<std::string, int64_t> fGMThresholds;

    SkQP(const SkQP&) = delete;
    SkQP& operator=(const SkQP&) = delete;
};
#endif  // skqp_DEFINED

