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

#ifndef WasmCommon_DEFINED
#define WasmCommon_DEFINED

#include <emscripten.h>
#include <emscripten/bind.h>
#include "include/core/SkColor.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSpan.h"
#include "include/private/base/SkMalloc.h"

#include <memory>

class SkData;
class SkCodec;

using namespace emscripten;

// Self-documenting types
using JSColor = int32_t;
using JSArray = emscripten::val;
using JSObject = emscripten::val;
using JSString = emscripten::val;
using SkPathOrNull = emscripten::val;
using TypedArray = emscripten::val;
using Uint8Array = emscripten::val;
using Uint16Array = emscripten::val;
using Uint32Array = emscripten::val;
using Float32Array = emscripten::val;

// If we are using C++ and EMSCRIPTEN_BINDINGS, we can't have primitive pointers in our function
// type signatures. (this gives an error message like "Cannot call foo due to unbound
// types Pi, Pf").  But, we can just pretend they are numbers and cast them to be pointers and
// the compiler is happy.
// These types refer to the TypedArray that the JS interface wrote into or will read out of.
// This doesn't stop us from using these as different types; e.g. a float* can be treated as an
// SkPoint* in some APIs.
using WASMPointerF32 = uintptr_t;
using WASMPointerI32 = uintptr_t;
using WASMPointerU8  = uintptr_t;
using WASMPointerU16 = uintptr_t;
using WASMPointerU32 = uintptr_t;
using WASMPointer = uintptr_t;

#define SPECIALIZE_JSARRAYTYPE(type, name)                  \
    template <> struct JSArrayType<type> {                  \
        static constexpr const char* const gName = name;    \
    }

template <typename T> struct JSArrayType {};

SPECIALIZE_JSARRAYTYPE( int8_t,    "Int8Array");
SPECIALIZE_JSARRAYTYPE(uint8_t,   "Uint8Array");
SPECIALIZE_JSARRAYTYPE( int16_t,  "Int16Array");
SPECIALIZE_JSARRAYTYPE(uint16_t, "Uint16Array");
SPECIALIZE_JSARRAYTYPE( int32_t,  "Int32Array");
SPECIALIZE_JSARRAYTYPE(uint32_t, "Uint32Array");
SPECIALIZE_JSARRAYTYPE(float,   "Float32Array");

#undef SPECIALIZE_JSARRAYTYPE

/**
 *  Create a typed-array (in the JS heap) and initialize it with the provided
 *  data (from the wasm heap).
 */
template <typename T> TypedArray MakeTypedArray(int count, const T src[]) {
    emscripten::val length = emscripten::val(count);
    emscripten::val jarray = emscripten::val::global(JSArrayType<T>::gName).new_(count);
    jarray.call<void>("set", val(typed_memory_view(count, src)));
    return jarray;
}

SkColor4f ptrToSkColor4f(WASMPointerF32);

std::unique_ptr<SkCodec> DecodeImageData(sk_sp<SkData>);

/**
 *  Gives read access to a JSArray
 *
 *  We explicitly use malloc/free (not new/delete) so this can be used with allocations from the JS
 *  side (ala CanvasKit.Malloc).
 */
template <typename T> class JSSpan {
public:
    // Note: Use of this constructor is 5-20x slower than manually copying the data on the JS side
    // and sending over a pointer, length, and boolean for the other constructor.
    JSSpan(JSArray src) {
        const size_t len = src["length"].as<size_t>();
        T* data;

        // If the buffer was allocated via CanvasKit' Malloc, we can peek directly at it!
        if (src["_ck"].isTrue()) {
            fOwned = false;
            data = reinterpret_cast<T*>(src["byteOffset"].as<size_t>());
        } else {
            fOwned = true;
            data = static_cast<T*>(sk_malloc_throw(len, sizeof(T)));

            // now actually copy into 'data'
            if (src.instanceof(emscripten::val::global(JSArrayType<T>::gName))) {
                auto dst_view = emscripten::val(typed_memory_view(len, data));
                dst_view.call<void>("set", src);
            } else {
                for (size_t i = 0; i < len; ++i) {
                    data[i] = src[i].as<T>();
                }
            }
        }
        fSpan = SkSpan(data, len);
    }

    JSSpan(WASMPointer ptr, size_t len, bool takeOwnership): fOwned(takeOwnership) {
        fSpan = SkSpan(reinterpret_cast<T*>(ptr), len);
    }

    ~JSSpan() {
        if (fOwned) {
            sk_free(fSpan.data());
        }
    }

    const T* data() const { return fSpan.data(); }
    size_t size() const { return fSpan.size(); }

private:
    SkSpan<T>   fSpan;
    bool        fOwned;
};

#endif
