/*
 * 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/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 Int32Array = 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<const 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.
    explicit 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
