#include <stdio.h>
#include "SPIFFS.h"

#include <string.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_spiffs.h"

static const char *TAG = "user_spiffs";

#include "esp_attr.h"

RTC_FAST_ATTR  Machine_info_t   Machine_info;
RTC_FAST_ATTR Node *Send_list = NULL;  //发送数据链表





void spiffs_init(void)
{
    esp_vfs_spiffs_conf_t conf = {
      .base_path = "/spiffs",
      .partition_label = NULL,
      .max_files = 5,
      .format_if_mount_failed = true
    };

    // Use settings defined above to initialize and mount SPIFFS filesystem.
    // Note: esp_vfs_spiffs_register is an all-in-one convenience function.
    esp_err_t ret = esp_vfs_spiffs_register(&conf);

    if (ret != ESP_OK) {
        if (ret == ESP_FAIL) {
            ESP_LOGE(TAG, "Failed to mount or format filesystem");
        } else if (ret == ESP_ERR_NOT_FOUND) {
            ESP_LOGE(TAG, "Failed to find SPIFFS partition");
        } else {
            ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
        }
        return;
    }


    size_t total = 0, used = 0;
    ret = esp_spiffs_info(conf.partition_label, &total, &used);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Failed to get SPIFFS partition information (%s). Formatting...", esp_err_to_name(ret));
        esp_spiffs_format(conf.partition_label);
        return;
    } else {
        ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);
    }


    // Check consistency of reported partiton size info.
    if (used > total) {
        ESP_LOGW(TAG, "Number of used bytes cannot be larger than total. Performing SPIFFS_check().");
        ret = esp_spiffs_check(conf.partition_label);
        // Could be also used to mend broken files, to clean unreferenced pages, etc.
        // More info at https://github.com/pellepl/spiffs/wiki/FAQ#powerlosses-contd-when-should-i-run-spiffs_check
        if (ret != ESP_OK) {
            ESP_LOGE(TAG, "SPIFFS_check() failed (%s)", esp_err_to_name(ret));
            return;
        } else {
            ESP_LOGI(TAG, "SPIFFS_check() successful");
        }
    }
}


void spiffs_write(Machine_info_t* info)
{
    ESP_LOGI(TAG, "File written");
    FILE* f = fopen("/spiffs/yc_data.bin", "w");
    if (f == NULL) {
        ESP_LOGE(TAG, "Failed to open file for writing");
        return;
    }
    fwrite(info,sizeof(Machine_info_t),1,f);
    fclose(f);
}



void spiffs_read(Machine_info_t* info)
{
    ESP_LOGI(TAG, "Reading file");
    FILE* f = fopen("/spiffs/yc_data.bin", "r");
    if (f == NULL) {
        ESP_LOGE(TAG, "Failed to open file for reading");
        return;
    }
    fread(info,sizeof(Machine_info_t),1,f);
    fclose(f);
}






void left_spiffs_write(uint8_t *buffer,unsigned int size)
{
    // ESP_LOGI(TAG, "left File written");
    FILE* f = fopen("/spiffs/left_display.bin", "w");
    if (f == NULL) {
        printf("Failed to open file for writing");
        return;
    }

    size_t bytes_written = 0;
    size_t bytes_to_write = size;

    while (bytes_written < size) {
        size_t write_result = fwrite(buffer + bytes_written, 1, bytes_to_write, f);

        if (write_result < 0) {
           printf("Error writing to file: left_display.bin\r\n");
            fclose(f);
            return;
        }

        bytes_written += write_result;
        bytes_to_write -= write_result;
    }



    fclose(f);
}



void left_spiffs_read(uint8_t *buffer, unsigned int  size)
{
    ESP_LOGI(TAG, "Reading left file");
    FILE* f = fopen("/spiffs/left_display.bin", "r");
    if (f == NULL) {
        printf("Failed to open file for reading");
        return;
    }

    size_t bytes_read = 0;
    size_t bytes_to_read = size;

    while (bytes_read < size) {
        size_t read_result = fread(buffer + bytes_read, 1, bytes_to_read, f);

        if (read_result < 0) {
            printf( "Error reading from file: left_display.bin\r\n");
            fclose(f);
            return;
        }

        bytes_read += read_result;
        bytes_to_read -= read_result;

        if (read_result == 0) {
            // 文件已经读取完毕
            break;
        }
    }
    fclose(f);
}






void right_spiffs_write(uint8_t *buffer,unsigned int  size)
{
    ESP_LOGI(TAG, "right File written");
    FILE* f = fopen("/spiffs/right_display.bin", "w");
    if (f == NULL) {
        printf("Failed to open file for writing\r\n");
        return;
    }

    size_t bytes_written = 0;
    size_t bytes_to_write = size;

    while (bytes_written < size) {
        size_t write_result = fwrite(buffer + bytes_written, 1, bytes_to_write, f);

        if (write_result < 0) {
           printf("Error writing to file: left_display.bin\r\n");
            fclose(f);
            return;
        }

        bytes_written += write_result;
        bytes_to_write -= write_result;
    }
    

    fclose(f);
}



void right_spiffs_read(uint8_t *buffer,unsigned int  size)
{
    ESP_LOGI(TAG, "Reading right file");
    FILE* f = fopen("/spiffs/right_display.bin", "r");
    if (f == NULL) {
        printf("Failed to open file for reading");
        return;
    }
    size_t bytes_read = 0;
    size_t bytes_to_read = size;

    while (bytes_read < size) {
        size_t read_result = fread(buffer + bytes_read, 1, bytes_to_read, f);

        if (read_result < 0) {
            printf( "Error reading from file: right_display.bin\r\n");
            fclose(f);
            return;
        }

        bytes_read += read_result;
        bytes_to_read -= read_result;

        if (read_result == 0) {
            // 文件已经读取完毕
            break;
        }
    }
    fclose(f);
}



size_t spiffs_read_powerOn(Machine_info_t* info)
{
    size_t ret;
    ESP_LOGI(TAG, "Reading powerOn file");
    FILE* f = fopen("/spiffs/yc_data.bin", "r");
    if (f == NULL) {
        printf("Failed to open file for reading");
        return 0;
    }
    ret = fread(info,sizeof(Machine_info_t),1,f);//返回的不一定是读取的字节数
    fclose(f);
    // ESP_LOGW(TAG,"ret  = %d",ret);
    // ESP_LOG_BUFFER_HEX(TAG,info,sizeof(Machine_info_t));
    return ret;
}