#include <iostream>
#include "pico/stdlib.h"
#include "../../radio-switch.h"
#include "pico/stdio.h"
#include "pico/multicore.h"
#include <map>                  // map
#include <time.h>
#include "hardware/watchdog.h"

#define BUFFER_SIZ 270

const uint LED_PIN = PICO_DEFAULT_LED_PIN;
const uint RADIO_TRANSMIT_PIN = 16; // 433发射模块引脚
const uint RADIO_RECEIVER_PIN = 17; // 433接收模块引脚
const uint PASSWD_LEN = 3;      // 随机数几位
const uint QUEUES_NUM = 3;      // 队列数量, 满了发送
const uint QUEUES_WAIT = 4;     // 队列等待时间, 单位秒, 队列未满时

char ins[] = "55";
char outs = '1';

// 闪烁LED
static void light()
{
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PIN, GPIO_OUT);
    gpio_put(LED_PIN, 1);
    sleep_ms(100);
    gpio_put(LED_PIN, 0);
    sleep_ms(100);

    return;
}

static const char pool[] = {
    '1', '2', '3', '4', '5', '6', '7', '8', '9'
};

// 随即数
static int RAND()
{
    char password[BUFFER_SIZ];
    int i = 0;
    FILE *fp;

    memset(password, 0, BUFFER_SIZ);
    srand(time(NULL));

    while (i != PASSWD_LEN) {
        password[i++] = pool[rand() % sizeof(pool)];
    }

    //printf("%d\n", atoi(password));
    return atoi(password);
}

static void SEND(const int ID)
{
    int RANDOM = 500;
    const int LOOP_NUM = 1;     // 循环发送次数
    const uint PULSE_LENGTH = 169; // set this to PULSELENGTH RECIEVED
    const uint REPEAT_TRANSMIT = 5; // set this to whatever works best for you.    // 重复发送
    const uint PROTOCOL = 1;    // set this to PROTOCOL RECIEVED
    const uint BIT_LENGTH = 24; // set this to BIT LENGTH RECIEVED

    gpio_init(RADIO_TRANSMIT_PIN);
    RCSwitch mySwitch = RCSwitch();
    mySwitch.enableTransmit(RADIO_TRANSMIT_PIN);
    mySwitch.setProtocol(PROTOCOL);
    mySwitch.setPulseLength(PULSE_LENGTH);
    mySwitch.setRepeatTransmit(REPEAT_TRANSMIT);

    for (int i = 1; i <= LOOP_NUM; i++) {
        RANDOM = RAND();
        light();                // 灯闪烁

        sleep_ms(RANDOM * 2 / 3); // 等待随机时间

        mySwitch.send(ID, BIT_LENGTH); // 发射
        sleep_ms(120);
    }

    return;
}

static int int_string(int val, char *inchars, int SIZE, int *inchars_len, char *outchars, int *outchars_len)
{
    memset(inchars, 0, SIZE);
    memset(outchars, 0, SIZE);

    snprintf(inchars, SIZE, "%d", val);
    *inchars_len = strlen(inchars);

    if (0 == strncasecmp(inchars, ins, 2)) {
        outchars[0] = outs;
        outchars[1] = outs;
        strncpy(outchars + 2, inchars + 2, (*inchars_len) - 2);

        *outchars_len = strlen(outchars);
    }

    return 0;
}

// 核心0发送数据到核心1, 核心1判断是否有数据到来, 然后打印.
static void core1_main()
{
    gpio_init(RADIO_RECEIVER_PIN);

    RCSwitch rcSwitch = RCSwitch();
    rcSwitch.enableReceive(RADIO_RECEIVER_PIN);

    char inchars[BUFFER_SIZ];
    char outchars[BUFFER_SIZ];
    int inchars_len;
    int outchars_len;

    while (true) {
        if (rcSwitch.available()) {
            light();            // 灯闪烁

            uint32_t val = rcSwitch.getReceivedValue();

            int_string(val, inchars, BUFFER_SIZ, &inchars_len, outchars, &outchars_len);

            if (val != 0) {
                if (inchars[0] == ins[0] && inchars[1] == ins[1]) {
                    multicore_fifo_push_blocking(atoi(outchars));
                } else {
                    rcSwitch.resetAvailable();
                    val = 0;
                    continue;
                }

            }

            rcSwitch.resetAvailable();
            val = 0;
        }

        sleep_ms(120);

    }

    return;
}

int main(void)
{
    stdio_init_all();
    sleep_ms(7000);
    
    std::map < int, int >idcode;
    int count=0;
    uint32_t i=0;
    

    multicore_reset_core1();
    multicore_launch_core1(core1_main);
    
    
    if (watchdog_caused_reboot()) {
        printf("Rebooted by Watchdog!\n");
    } else {
        printf("Clean boot\n");
    }
    
    watchdog_enable(8000, 1);
    

    while (1)
    {
        watchdog_update();
        
        if (multicore_fifo_rvalid())
        {
            i = multicore_fifo_pop_blocking();          // 读取核心1发送来的数据

            idcode.insert( {                            // 插入map
                          i, i}
            );
            
        }
        
        
        if (idcode.size() >= QUEUES_NUM)                // 等于3个时发送
        {
            for (auto it: idcode)
            {
                watchdog_update();
                printf("核心0转发433MHZ 1bin %u\n", it.first);
                SEND(it.first);
            }

            idcode.clear();
        }
        else                                            // 一直没有3个时候, 过一段时间发送
        {
            count++;                                    // 计数
            
            if (count == (QUEUES_WAIT*10))              // 秒
            {
                for (auto it: idcode)
                {
                    watchdog_update();
                    printf("核心0转发433MHZ 2bin %u\n", it.first);
                    SEND(it.first);
                }

                idcode.clear();
                count = 0;
            }
        }

        
        sleep_ms(100);
    }

    return 0;
}

