/*
 * 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(const uint8_t* data, size_t size) : fData(data), fSize(size), fNextByte(0) {}
    Fuzz() = delete;

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

    // Returns the total number of "random" bytes available.
    size_t size() const {
        return fSize;
    }

    // Returns if there are no bytes remaining for fuzzing.
    bool exhausted() const {
        return fSize == fNextByte;
    }

    void deplete() {
        fNextByte = fSize;
    }

    size_t remainingSize() const {
        return fSize - fNextByte;
    }

    const uint8_t *remainingData() const {
        return fData + fNextByte;
    }

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

    const uint8_t *fData;
    size_t fSize;
    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
