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

#ifndef Fuzz_DEFINED
#define Fuzz_DEFINED

#include "include/core/SkData.h"
#include "include/core/SkImageFilter.h"
#include "include/core/SkRegion.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkMalloc.h"
#include "include/private/base/SkTFitsIn.h"
#include "tools/Registry.h"

#include <limits>
#include <cmath>
#include <signal.h>
#include <limits>

class Fuzz {
public:
    explicit Fuzz(sk_sp<SkData> bytes) : fBytes(bytes), fNextByte(0) {}
    Fuzz() = delete;

    // Make noncopyable
    Fuzz(Fuzz&) = delete;
    Fuzz& operator=(Fuzz&) = delete;

    // Returns the total number of "random" bytes available.
    size_t size() { return fBytes->size(); }
    // Returns if there are no bytes remaining for fuzzing.
    bool exhausted() {
        return fBytes->size() == fNextByte;
    }

    size_t remaining() {
        return fBytes->size() - fNextByte;
    }

    void deplete() {
        fNextByte = fBytes->size();
    }

    // next() loads fuzzed bytes into the variable passed in by pointer.
    // We use this approach instead of T next() because different compilers
    // evaluate function parameters in different orders. If fuzz->next()
    // returned 5 and then 7, foo(fuzz->next(), fuzz->next()) would be
    // foo(5, 7) when compiled on GCC and foo(7, 5) when compiled on Clang.
    // By requiring params to be passed in, we avoid the temptation to call
    // next() in a way that does not consume fuzzed bytes in a single
    // platform-independent order.
    template <typename T>
    void next(T* t) { this->nextBytes(t, sizeof(T)); }

    // This is a convenient way to initialize more than one argument at a time.
    template <typename Arg, typename... Args>
    void next(Arg* first, Args... rest);

    // nextRange returns values only in [min, max].
    template <typename T, typename Min, typename Max>
    void nextRange(T*, Min, Max);

    // nextEnum is a wrapper around nextRange for enums.
    template <typename T>
    void nextEnum(T* ptr, T max);

    // nextN loads n * sizeof(T) bytes into ptr
    template <typename T>
    void nextN(T* ptr, int n);

    void signalBug(){
        // Tell the fuzzer that these inputs found a bug.
        SkDebugf("Signal bug\n");
        raise(SIGSEGV);
    }

    // Specialized versions for when true random doesn't quite make sense
    void next(bool* b);
    void next(SkRegion* region);

    bool nextBool() {
        bool b;
        this->next(&b);
        return b;
    }

    void nextRange(float* f, float min, float max);

private:
    template <typename T>
    T nextT();

    sk_sp<SkData> fBytes;
    size_t fNextByte;
    friend void fuzz__MakeEncoderCorpus(Fuzz*);

    void nextBytes(void* ptr, size_t size);
};

template <typename Arg, typename... Args>
inline void Fuzz::next(Arg* first, Args... rest) {
   this->next(first);
   this->next(rest...);
}

template <typename T, typename Min, typename Max>
inline void Fuzz::nextRange(T* value, Min min, Max max) {
    // UBSAN worries if we make an enum with out of range values, even temporarily.
    using Raw = typename sk_strip_enum<T>::type;
    Raw raw;
    this->next(&raw);

    if (raw < (Raw)min) { raw = (Raw)min; }
    if (raw > (Raw)max) { raw = (Raw)max; }
    *value = (T)raw;
}

template <typename T>
inline void Fuzz::nextEnum(T* value, T max) {
    // This works around the fact that UBSAN will assert if we put an invalid
    // value into an enum. We might see issues with enums being represented
    // on Windows differently than Linux, but that's not a thing we can fix here.
    using U = typename std::underlying_type<T>::type;
    U v;
    this->next(&v);
    if (v < (U)0) { *value = (T)0; return;}
    if (v > (U)max) { *value = (T)max; return;}
    *value = (T)v;
}

template <typename T>
inline void Fuzz::nextN(T* ptr, int n) {
   for (int i = 0; i < n; i++) {
       this->next(ptr+i);
   }
}

struct Fuzzable {
    const char* name;
    void (*fn)(Fuzz*);
};

// Not static so that we can link these into oss-fuzz harnesses if we like.
#define DEF_FUZZ(name, f)                                               \
    void fuzz_##name(Fuzz*);                                            \
    sk_tools::Registry<Fuzzable> register_##name({#name, fuzz_##name}); \
    void fuzz_##name(Fuzz* f)

#endif//Fuzz_DEFINED
