/*
 * Gimbal
 * Copyright (C) 2024 moonleay
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package net.moonleay.gimbal.networking

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.cbor.Cbor
import kotlinx.serialization.decodeFromByteArray
import kotlinx.serialization.encodeToByteArray
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs
import net.minecraft.network.PacketByteBuf
import net.moonleay.gimbal.client.editor.ClientEditor
import net.moonleay.gimbal.editor.state.EditorState
import net.moonleay.gimbal.editor.util.GimbalPolicy

object GimbalClient {

    fun registerPacketHandlers() {
        ClientPlayNetworking.registerGlobalReceiver(PacketIDs.TRANSFER_GIMBLE_POLICY_ID) { _, _, buf, _ ->
            onAllowedCheck(buf)
        }
    }

    @OptIn(ExperimentalSerializationApi::class)
    private fun onAllowedCheck(buf: PacketByteBuf) {
        val policy = Cbor.decodeFromByteArray<GimbalPolicy>(buf.readByteArray())
        ClientEditor.onAllowedCheck(policy) // Update the client's policy
    }

    /**
     * Sends the given [EditorState] to the server.
     */
    @OptIn(ExperimentalSerializationApi::class)
    fun sendEditorState(state: EditorState) {
        val buf = PacketByteBufs.create()
        buf.writeByteArray(Cbor.encodeToByteArray(state))
        ClientPlayNetworking.send(PacketIDs.UPDATE_EDITOR_STATE_ID, buf)
    }

    @OptIn(ExperimentalSerializationApi::class)
    fun checkIfServerHasGimble(state: EditorState) {
        val buf = PacketByteBufs.create()
        buf.writeByteArray(Cbor.encodeToByteArray(state))
        ClientPlayNetworking.send(PacketIDs.GIMBLE_PRERENCE_CHECK_ID, buf)
    }
}
