using System;
using System.Runtime.InteropServices;

namespace OkonaPad
{
    /// <summary>
    /// Thin bridge to the JavaScript side. In a WebGL build these resolve to the
    /// functions in <c>Plugins/OkonaInterop.jslib</c>:
    ///   OkonaReadState — copies the shell's snapshot (window.__okonaPad) straight
    ///                    into this buffer's WebAssembly memory (zero copies/strings).
    ///   OkonaRumble    — forwards a rumble request to window.okonaOnRumble.
    /// In the Editor (and any non-WebGL player) there's no JS layer, so reads come
    /// from <see cref="EditorInject"/> (used by tests/simulators) and rumble is a no-op.
    /// </summary>
    internal static class OkonaInterop
    {
#if UNITY_WEBGL && !UNITY_EDITOR
        [DllImport("__Internal")] private static extern int OkonaReadState(byte[] buffer, int maxLen);
        [DllImport("__Internal")] private static extern void OkonaRumble(int slot, float low, float high);

        public static int ReadState(byte[] buffer) => OkonaReadState(buffer, buffer.Length);
        public static void Rumble(int slot, float low, float high) => OkonaRumble(slot, low, high);
#else
        /// <summary>Editor/test injection point — set this to a snapshot buffer to simulate the JS layer.</summary>
        public static byte[] EditorInject;

        public static int ReadState(byte[] buffer)
        {
            if (EditorInject == null) return 0;
            int n = Math.Min(buffer.Length, EditorInject.Length);
            Array.Copy(EditorInject, buffer, n);
            return n;
        }

        public static void Rumble(int slot, float low, float high) { /* no JS layer outside WebGL */ }
#endif
    }
}
