// Author: NiuJiuRu
// Email: niujiuru@qq.com
// Date: 2025-11-20

package mcu_ctrl_board

/*
#include "mcu_ctrl_board.h"
*/
import "C"

import (
	"encoding/json"
	"fmt"
	"unsafe"

	"hnyfkj.com.cn/rtu/linux/baseapp"
	"hnyfkj.com.cn/rtu/linux/utils/jsonrpc2"
)

// 打开与MCU控制板的串口通讯
func mcuCtrlBoard_ComInit() (int, error) {
	ret := int(C.MCBComInit())
	if ret != 0 {
		return ret, fmt.Errorf("an error occurred while calling the C.MCBComInit function(%d)", ret)
	}
	return 0, nil
}

// 关闭与MCU控制板的串口通讯
func mcuCtrlBoard_ComExit() error {
	ret := int(C.MCBComExit())
	if ret != 0 {
		return fmt.Errorf("an error occurred while calling the C.MCBComExit function(%d)", ret)
	}
	return nil
}

// 主动的发送指令给MCU控制板
func mcuCtrlBoard_SendCmd(cmd string) error {
	cstr := C.CString(cmd)
	defer C.free(unsafe.Pointer(cstr)) // C.CString()分配的堆内存Go侧自己释放

	ret := int(C.MCBComSendCmd(cstr))
	if ret != 0 {
		return fmt.Errorf("an error occurred while calling the C.MCBComSendCmd function(%d)", ret)
	}
	return nil
}

// 判断输入字符串是请求/应答
func detectJsonRole(jsonStr string) string {
	var obj map[string]json.RawMessage
	if json.Unmarshal([]byte(jsonStr), &obj) != nil {
		return "invalid"
	}
	switch {
	case obj["method"] != nil:
		return "request"
	case obj["result"] != nil || obj["error"] != nil:
		return "response"
	default:
		return "unknown"
	}
}

//export RTU_JsonMsgProcCb
func RTU_JsonMsgProcCb(jsonStr *C.char) *C.char {
	s := C.GoString(jsonStr)
	role := detectJsonRole(s)

	var w *jsonrpc2.Response

	wret := func() *C.char {
		if w == nil { // 无应答
			return nil
		}
		// 下面由C.CString()分配的堆内存由C侧释放
		b, err := w.String()
		if err != nil {
			return C.CString(fmt.Sprintf("an error occurred while calling the String() method of jsonrpc2.Response: %v", err))
		}
		return C.CString(b)
	}

	if role == "response" {
		err := Board.handleResponse(s)
		if err != nil {
			baseapp.Logger.Errorf("[%s] 解析控制板返回的应答时发生错误: %v", MODULE_NAME, err)
		}
		return nil
	}

	if role != "request" {
		w = jsonrpc2.BuildError(nil, jsonrpc2.ErrInvalidRequest, "")
		return wret()
	}

	r, err := jsonrpc2.ParseRequest(s)

	call := func(f func(*jsonrpc2.Request) (*jsonrpc2.Response, error)) *jsonrpc2.Response {
		w, e := f(r)
		if e != nil { // 调用本地RPC处理函数时发生错误
			return jsonrpc2.BuildError(r, jsonrpc2.ErrInternal, "")
		}
		return w
	}

	if err != nil {
		w = jsonrpc2.BuildError(nil, jsonrpc2.ErrParse, "")
	} else {
		switch r.Method {
		// 控制板查询数据板状态
		case "get_rtu_status":
			w = call(Board.getRTUStatus)
		// 控制板发送传感器数据
		case "send_sensor_data":
			w = call(Board.sendSensorData)
		// 控制板请求数据板拍照
		case "take_photo":
			w = call(Board.takePhoto)
		// 控制板发送预掉电通知
		case "power_down":
			w = call(Board.powerDown)
		default:
			w = jsonrpc2.BuildError(r, jsonrpc2.ErrMethodNotFound, "")
		}
	}

	return wret()
}
