#include "log.h"
/*

w+以纯文本方式读写，而wb+是以二进制方式进行读写。

mode说明：

w 打开只写文件，若文件存在则文件长度清为0，即该文件内容会消失。若文件不存在则建立该文件。

w+ 打开可读写文件，若文件存在则文件长度清为零，即该文件内容会消失。若文件不存在则建立该文件。

wb 只写方式打开或新建一个二进制文件，只允许写数据。

wb+ 读写方式打开或建立一个二进制文件，允许读和写。

r 打开只读文件，该文件必须存在，否则报错。

r+ 打开可读写的文件，该文件必须存在，否则报错。

rb+ 读写方式打开一个二进制文件，只允许读写数据。

a 以附加的方式打开只写文件。若文件不存在，则会建立该文件，如果文件存在，写入的数据会被加到文件尾，即文件原先的内容会被保留。(EOF符保留)

a+ 以附加方式打开可读写的文件。若文件不存在，则会建立该文件，如果文件存在，写入的数据会被加到文件尾后，即文件原先的内容会被保留。 (原来的EOF符不保留)

ab+ 读写打开一个二进制文件，允许读或在文件末追加数据。

加入b 字符用来告诉函数库打开的文件为二进制文件，而非纯文字文件。
*/


String pathforlog = "/log.txt";
dateandtime start_offset_datetime = {2024, 1, 1, 0, 0, 0}; // 设置起始时间为2024-01-01 00:00:00
uint64_t  start_offset_mcu_time= 0; // 2024-01-01 00:00:00对应的Unix时间戳


void setpathforlog(String path)
{
    pathforlog = path;
}

bool isLeapYear(int year) {
    return (year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0));
}

int daysInMonth(int year, int month) {
    static const int days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
    if (month == 2 && isLeapYear(year)) return 29;
    return days[month - 1];
}

void tmaddseconds(dateandtime &tm, long long n) {
    // 先加秒
    tm.second += n;

    // 秒转分钟
    tm.minute += tm.second / 60;
    tm.second %= 60;

    // 分钟转小时
    tm.hour += tm.minute / 60;
    tm.minute %= 60;

    // 小时转天
    tm.day += tm.hour / 24;
    tm.hour %= 24;

    // 处理日/月/年的进位
    while (true) {
        int dim = daysInMonth(tm.year, tm.month);
        if (tm.day <= dim) break;
        tm.day -= dim;
        tm.month++;
        if (tm.month > 12) {
            tm.month = 1;
            tm.year++;
        }
    }
}


void setoffsettime(dateandtime tm)
{
    start_offset_datetime = tm;
    start_offset_mcu_time = millis();
}



void write_log_def(unsigned char level,String write_data)
{
    write_log(pathforlog,level,write_data);
}
String two(int v) {
  if (v < 10) return "0" + String(v);
  return String(v);
}
String getlocaltime()
{
    unsigned long uptime = millis();
    long time_diff = uptime - start_offset_mcu_time;

    long seconds = time_diff / 1000;
    long milliseconds = time_diff % 1000;
    dateandtime tm = start_offset_datetime;
    tmaddseconds(tm, seconds);
    String timestr=String(tm.year) + "-"+two(tm.month) +"-" + two(tm.day) + " " + two(tm.hour) + ":" + two(tm.minute) + ":" + two(tm.second);
    return timestr;
}


void write_log(String path,unsigned char level,String write_data)
{
    //return;
#ifdef ceshi
    Serial.println(write_data);
#endif

    if(level > 10) {
        //保存本地，和同时上传云端，小于10只保存本地
    }
    

    unsigned long uptime = millis();
    long time_diff = uptime - start_offset_mcu_time;

    long seconds = time_diff / 1000;
    long milliseconds = time_diff % 1000;
    dateandtime tm = start_offset_datetime;
    tmaddseconds(tm, seconds);


    String timeString = String(tm.year) + "-"+two(tm.month) +"-" + two(tm.day) + " " + two(tm.hour) + ":" + two(tm.minute) + ":" + two(tm.second)+ "." + String(milliseconds);
    write_data = timeString + ":" + write_data;
    sdcard::lock();
    File file;
      file = SD_MMC.open(path,"ab+");
      file.println(write_data);
      file.flush();
      file.close();
        sdcard::unlock();
}
