/* ESP32 UWB Application(Anchor/Tag)

   Copyright (c) 2025, Skytrack software Studio.
   All rights reserved.

   Author: Zhang Xiaolong
   Date: 2025-07-17
   Version: 1.0.0
   Description: This file is the entry point of the UWB application.
*/
#include "sdkconfig.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "esp_heap_caps.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "bsp.h"
#include "display/display_ssd1306_lvgl.h"
#include "ws2812.h"
#include "main.h"

#include "dw3000_hw.h"
#include "dw3000_spi.h"
#include "dw3000_hw.h"
#include "dw3000_spi.h"

static const char* TAG = "main";

void task_uwb_test(void* p_arg)
{
	(void)p_arg;

	DW3000_PIN_CONFIG dw3000_pin_config = {
		.dw3000_pin_reset = CONFIG_DW3000_GPIO_RESET,
		.dw3000_pin_wakeup = CONFIG_DW3000_GPIO_WAKEUP,
		.dw3000_pin_irq = CONFIG_DW3000_GPIO_IRQ,
		.dw3000_pin_cs = CONFIG_DW3000_SPI_CS,
		.dw3000_pin_clk = CONFIG_DW3000_SPI_CLK,
		.dw3000_pin_miso = CONFIG_DW3000_SPI_MISO,
		.dw3000_pin_mosi = CONFIG_DW3000_SPI_MOSI,
	};

	dw3000_hw_init(&dw3000_pin_config);
	dw3000_hw_reset();

#include "examples_info/examples_defines.h"
	extern example_ptr example_pointer;
	extern void build_examples(void);

	ESP_LOGI(TAG, "task_uwb_test() start...");
	build_examples();
	example_pointer(); // 运行选定的示例

	while (1) {
		vTaskDelay(1000 / portTICK_PERIOD_MS);
	}
}

void test_run_info(unsigned char* data)
{
	ESP_LOGI("EXAMPLE", "%s", data);
}


void app_main(void)
{
	ESP_LOGI(TAG, "app_main() start...");
	gpio_init_for_debug();
	ESP_LOGI(TAG, "gpio_init_for_debug() OK...");

	bsp_init();
	ESP_LOGI(TAG, "bsp_init() OK...");

	{
		indicator_backlight_init();
		indicator_backlight_set_brightness(0xFF);
		alive_led_init();
	}


	/* Initialize WS2812 as early as possible to avoid power-on random latching */
	ws2812_init();
	ESP_LOGI(TAG, "ws2812_init() OK...");

	esp_err_t oled_ret = oled_display_init();
	if (oled_ret != ESP_OK) {
		ESP_LOGW(TAG, "OLED init failed: %s", esp_err_to_name(oled_ret));
	}
	else {
		// oled_request_network_refresh();
		// oled_text_set_at(0, oled_compute_cjk_row_y(0), "Line 0 你好！Hello, World!");
		// oled_text_set_at(0, oled_compute_cjk_row_y(1), "Line 1 你好! Hello, World!");
		// oled_text_set_at(0, oled_compute_cjk_row_y(2), "Line 2 你好! Hello, World!");
		// oled_text_set_at(0, oled_compute_cjk_row_y(3), "Line 3 你好! Hello, World!");
		// oled_text_set_at(0, oled_compute_cjk_row_y(4), "Line 4 你好! Hello, World!");
		// oled_text_set_at(0, oled_compute_cjk_row_y(5), "Line 5 你好！Hello, World!");
	}

	xTaskCreatePinnedToCore(task_uwb_test, "task_uwb_test", TASK_UWB_TEST_STACK_SIZE, (void*)NULL, TASK_UWB_TEST_PRIO, NULL, 1); //CORE0

	set_system_status(SYSTEM_STATUS_WORKING);

	while (1) {
		check_alive_led();

		if (cfg_button_pressed) {
			cfg_button_pressed = 0;
			ESP_LOGI(TAG, "cfg button pressed");

			static uint8_t brightness = 255;
			brightness -= 0x10;
			if (brightness < 0x10) {
				brightness = 0x00;
			}
			if (brightness >= 0xF0) {
				brightness = 0xFF;
			}
			indicator_backlight_set_brightness(brightness);

			//extern void print_task_list(void);
			//print_task_list();
		}
		else if (cfg_button_long_pressed) {
			ESP_LOGI(TAG, "cfg button long pressed");
			cfg_button_long_pressed = 0;

			static uint8_t on = 0;
			if (on == 0) {
				static uint32_t color = 0;
				static uint8_t cidx = 0;
				cidx++;
				if (cidx > 3) {
					cidx = 0;
				}
				switch (cidx) {
				case 0:
					color = 0x0000FF;
					break;
				case 1:
					color = 0x00FF00;
					break;
				case 2:
					color = 0xFF0000;
					break;
				default:
					color = 0xFFFFFF;
					break;
				}
				set_identify_led_color(color);
				set_identify_led_on();
				on = 1;
			}
			else {
				set_identify_led_off();
				on = 0;
			}

		}
		else if (cfg_button_long_pressed_from_boot) {
			cfg_button_long_pressed_from_boot = 0;
			ESP_LOGI(TAG, "cfg button long pressed from boot");

		}
		else {
			// ESP_LOGI(TAG, "cfg button not pressed");
		}

		vTaskDelay(10 / portTICK_PERIOD_MS);
	}

}

void print_task_list(void)
{

	printf("当前内存剩余情况 (多类型) :\n");
	printf("  free heap (MALLOC_CAP_DEFAULT) : %u bytes\n",
		(unsigned)heap_caps_get_free_size(MALLOC_CAP_DEFAULT));
	printf("  free heap (MALLOC_CAP_INTERNAL): %u bytes\n",
		(unsigned)heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
	printf("  free heap (MALLOC_CAP_DMA)      : %u bytes\n",
		(unsigned)heap_caps_get_free_size(MALLOC_CAP_DMA));
	printf("  free heap (MALLOC_CAP_8BIT)    : %u bytes\n",
		(unsigned)heap_caps_get_free_size(MALLOC_CAP_8BIT));
	printf("  free heap (MALLOC_CAP_SPIRAM)  : %u bytes\n",
		(unsigned)heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
	printf("  free heap (MALLOC_CAP_32BIT)   : %u bytes\n",
		(unsigned)heap_caps_get_free_size(MALLOC_CAP_32BIT));
	printf("  largest free block (DEFAULT)  : %u bytes\n",
		(unsigned)heap_caps_get_largest_free_block(MALLOC_CAP_DEFAULT));
	printf("\n");

	// 预留足够的缓冲区来保存任务列表字符串
	// 每个任务大约需要 40 个字节
	char buffer[1024];

	printf("\n任务名称\t状态\t优先级\t剩余栈(字)\t任务编号\t核ID\n");
	printf("----------------------------------------------------------------\n");
	vTaskList(buffer);
	printf("%s", buffer);
	printf("----------------------------------------------------------------\n");
	printf("注: '剩余栈' 是高水位线 (High Water Mark), 值越小表示栈越紧张。\n\n");

}
