//
// Created by Matthew on 2023/12/27.
//

#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>


#include "GPIOControl.h"

#ifdef _DEBUG
#include <AndroidHelper.h>
#endif

#define IOT_PARAM_WRITE 0xAE
#define IOT_PARAM_READ 0xAF
#define MAX_STRING_LEN 32

typedef struct
{
    int cmd;
    int value;
    int result;
    long value2;
    char str[MAX_STRING_LEN];
}IOT_PARAM;

void GpioControl::setInt(int cmd, int value)
{
    int fd = open(GPIO_NODE_MP, O_RDONLY);
    IOT_PARAM param;
    param.cmd = cmd;
    param.value = value;
    // LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value);
    if( fd > 0 )
    {
        int res = ioctl(fd, IOT_PARAM_WRITE, &param);
        // LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result);
        close(fd);
    }
    return;
}

int GpioControl::getInt(int cmd)
{
    int fd = open(GPIO_NODE_MP, O_RDONLY);
    // LOGE("get_int fd=%d,cmd=%d\r\n",fd, cmd);
    if( fd > 0 )
    {
        IOT_PARAM param;
        param.cmd = cmd;
        ioctl(fd, IOT_PARAM_READ, &param);
#ifdef _DEBUG
        ALOGI("getInt cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result);
#endif
        close(fd);
        return param.value;
    }
    return -1;
}

void GpioControl::setLong(int cmd, long value)
{
    int fd = open(GPIO_NODE_MP, O_RDONLY);
    IOT_PARAM param;
    param.cmd = cmd;
    param.value2 = value;
    // LOGE("set_long fd=%d,cmd=%d,value2=%ld\r\n",fd, param.cmd, param.value2);

    if( fd > 0 )
    {
        ioctl(fd, IOT_PARAM_WRITE, &param);
        // LOGE("set_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result);
        close(fd);
    }
}

long GpioControl::getLong(int cmd)
{
    int fd = open(GPIO_NODE_MP, O_RDONLY);
    // LOGE("get_long fd=%d,cmd=%d\r\n",fd, cmd);
    if( fd > 0 )
    {
        IOT_PARAM param;
        param.cmd = cmd;
        ioctl(fd, IOT_PARAM_READ, &param);
        // LOGE("get_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result);
        close(fd);
        return param.value2;
    }
    return -1;
}

void GpioControl::setString(int cmd, const std::string& value)
{
    IOT_PARAM param;
    int fd = open(GPIO_NODE_MP, O_RDONLY);
    int len = MAX_STRING_LEN < value.size() ? MAX_STRING_LEN : value.size();

    param.cmd = cmd;
    memset(param.str, 0, MAX_STRING_LEN);
    memcpy(param.str, value.c_str(), len);
    // LOGE("set_string fd=%d,cmd=%d,str=%s\r\n",fd, param.cmd, param.str);
    if( fd > 0 )
    {
        ioctl(fd, IOT_PARAM_WRITE, &param);
        // LOGE("set_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result);
        close(fd);
    }
    return;
}

std::string GpioControl::getString(int cmd)
{
    int fd = open(GPIO_NODE_MP, O_RDONLY);
    // LOGE("get_string fd=%d,cmd=%d\r\n",fd, cmd);
    if( fd > 0 )
    {
        IOT_PARAM param;
        param.cmd = cmd;
        ioctl(fd, IOT_PARAM_READ, &param);
        // LOGE("get_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result);
        close(fd);
        return std::string(param.str);
    }
    return "";
}

#ifdef USING_N938

bool GpioControl::SetN938Cmd(int cmd, int val)
{
    char buf[32] = { 0 };
    snprintf(buf, "out %d %d", cmd, val);

    IOT_PARAM param;
    int len = MAX_STRING_LEN < strlen(buf) ? MAX_STRING_LEN : strlen(buf);

    param.cmd = cmd;
    memset(param.str, 0, MAX_STRING_LEN);
    memcpy(param.str, value.c_str(), len);

    int fd = open(GPIO_NODE_MP, O_RDONLY);
    if( fd > 0 )
    {
        ioctl(fd, IOT_PARAM_WRITE, &param);
        close(fd);
    }
    return;
}

bool GpioControl::OpenSensors()
{

    GpioControl::setCam3V3Enable(true);
    GpioControl::setInt(CMD_SET_485_EN_STATE, true ? 1 : 0);
    int     igpio;
    GpioControl::setInt(CMD_SET_WTH_POWER, 1);
    GpioControl::setInt(CMD_SET_PULL_POWER, 1);
    GpioControl::setInt(CMD_SET_ANGLE_POWER, 1);
    GpioControl::setInt(CMD_SET_OTHER_POWER, 1);
    GpioControl::setInt(CMD_SET_PIC1_POWER, 1);

    igpio = GpioControl::getInt(CMD_SET_WTH_POWER);
    igpio = GpioControl::getInt(CMD_SET_PULL_POWER);
    igpio = GpioControl::getInt(CMD_SET_ANGLE_POWER);
    igpio = GpioControl::getInt(CMD_SET_OTHER_POWER);
    igpio = GpioControl::getInt(CMD_SET_PIC1_POWER);

    GpioControl::setInt(CMD_SET_SPI_POWER, 1);
    GpioControl::setInt(CMD_SET_485_en0, 1);
    GpioControl::setInt(CMD_SET_485_en1, 1);
    GpioControl::setInt(CMD_SET_485_en2, 1);
    GpioControl::setInt(CMD_SET_485_en3, 1);
    GpioControl::setInt(CMD_SET_485_en4, 1);

    igpio = GpioControl::getInt(CMD_SET_SPI_POWER);
    igpio = GpioControl::getInt(CMD_SET_485_en0);
    igpio = GpioControl::getInt(CMD_SET_485_en1);
    igpio = GpioControl::getInt(CMD_SET_485_en2);
    igpio = GpioControl::getInt(CMD_SET_485_en3);
    igpio = GpioControl::getInt(CMD_SET_485_en4);
    return 0;

}

#endif
