/*****************************************************************************
 * file    lib/process/main.c  
 * author  YuLiang
 * version 1.0.0
 * date    26-Sep-2021
 * brief   This file provides all the main related operation functions.
 ******************************************************************************
 * Attention
 *
 * <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *   1. Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright notice,
 *      this list of conditions and the following disclaimer in the documentation
 *      and/or other materials provided with the distribution.
 *   3. Neither the name of LandPower nor the names of its contributors may be used to 
 *      endorse or promote products derived from this software without specific
 *      prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ******************************************************************************/

/* Includes ------------------------------------------------------------------*/
//#ifdef HAVE_CONFIG_H
#include "config.h"
//#endif

/* 标准C库头文件. */
#include <locale.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/rtc.h>
#include <time.h>

#include "cmd.h"
#include "mtimer.h"
#include "main.h"
#include "hwgpio.h"
#include "fifo.h"

#include "pd_main.h"
#include "pd_dau.h"
#include "hwgpio.h"

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
int32_t recv_qid;
uint16_t version_hex;
uint32_t start_time;

static int8_t is_system_reboot;

static reboot_msg_t _reboot_msg[] = 
{
    {REBOOT_NONE, "Reboot none."},
    {REBOOT_LOCAL_SERVER_IP_CHANGE, "Reboot by debug tool has changed server."},
    {REBOOT_LOCAL_IP_CHANGE, "Reboot by debug tool has changed device ip."},
    {REBOOT_LOCAL_HOST_NAME_CHANGE, "Reboot by debug tool has changed device id."},
    {REBOOT_LOCAL_RESET, "Reboot by debug tool reset."},
    {REBOOT_LOCAL_ARM_UPGRADE, "Reboot by debug tool softwave upgrade."},
    {REBOOT_REMOTE_SERVER_IP_CHANGE, "Reboot by remote has changed server."},
    {REBOOT_REMOTE_IP_CHANGE, "Reboot by remote has changed device ip."},
    {REBOOT_REMOTE_HOST_NAME_CHANGE, "Reboot by remote has changed device id."},
    {REBOOT_REMOTE_DEVINFO_CHANGE, "Reboot by remote has changed device info."},
    {REBOOT_REMOTE_RESET, "Reboot by remote reset."},
    {REBOOT_UPGRADE_ALL, "Reboot by softwave upgrade."},
    {REBOOT_SYSTEM_RESET, "Reboot by command."},
    {REBOOT_MAX, NULL}
};

/* Private function prototypes -----------------------------------------------*/

/* Internal functions --------------------------------------------------------*/
/* 信号处理函数 */
void _signal_handler(int sig)
{
    if (SIGSEGV == sig)
    {
        log_backtrace(LOG_LVL_ERR);
    }
    //else if(SIGINT == sig
    //    || SIGTSTP == sig)
    //{
        /* 屏蔽信号 */
    //    return;
    //}

    exit(-1);
}

/* description: 设备重启函数
   param: module -- 记录在 哪个log 模块
          type   -- 重启原因
   return: */
void reboot_system(int module, REBOOT_MSG type)
{
    char *pmsg = NULL;

    is_system_reboot = TRUE;
    
    for (REBOOT_MSG i = REBOOT_NONE; i < REBOOT_MAX; i++)
    {
        if (_reboot_msg[i].type == type)
        {
            pmsg = _reboot_msg[i].msg;
            break;
        }
    }
    
    if (pmsg)
    {
        log_out(module, LOG_LVL_WARN, pmsg);
        system("sync");
    }

    sleep(3);
    system("reboot -f");
}

int32_t rtc_time_set(void)
{
    int rtc_fd;
    struct rtc_time rtc_tm;
    
    // 打开 RTC 设备
    rtc_fd = open("/dev/rtc0", O_RDWR);
    if (rtc_fd == -1) {
        DBG(DBG_M_DBG, "Unable to open RTC device\n");
        return -1;
    }

    // 设置当前时间（设置为2023年2月24日 12:00:00）
    rtc_tm.tm_year = 2045 - 1900;  // 年份需要减去1900
    rtc_tm.tm_mon = 1;             // 2月
    rtc_tm.tm_mday = 24;            // 24号
    rtc_tm.tm_hour = 12;
    rtc_tm.tm_min = 0;
    rtc_tm.tm_sec = 0;

    if (ioctl(rtc_fd, RTC_SET_TIME, &rtc_tm) == -1) {
        DBG(DBG_M_DBG, "Unable to set RTC time\n");
        close(rtc_fd);
        return -1;
    }

    DBG(DBG_M_DBG, "RTC time set successfully\n");

    close(rtc_fd);
    return 0;
}

int32_t rtc_time_get(void)
{
    time_t timestamp;
    
        DBG(DBG_M_DBG, "rtc_time_get start!!!!!!!!\r\n");
    int fd = open("/dev/rtc0", O_RDONLY);
    if (fd == -1) {
        DBG(DBG_M_DBG, "打开设备文件失败\r\n");
        
        return 1;
    }

    // 定义存储时间的结构体
    struct rtc_time tm;
    // 使用 ioctl 调用 RTC_RD_TIME 命令读取时间
    if (ioctl(fd, RTC_RD_TIME, &tm) == -1) {
        DBG(DBG_M_DBG, "读取时间失败\r\n");
        close(fd);
        return 1;
    }
    // 转换为 Unix 时间戳
    timestamp = mktime((struct tm*)&tm);
    if (timestamp == -1) {
        fprintf(stderr, "mktime failed\n");
        return EXIT_FAILURE;
    }
    // 关闭设备文件
    close(fd);

    // 输出读取到的时间
    DBG(DBG_M_DBG, "当前时间: %04d-%02d-%02d %02d:%02d:%02d\n",
           tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
           tm.tm_hour, tm.tm_min, tm.tm_sec);
    DBG(DBG_M_DBG, "Unix timestamp: %ld\n", timestamp);

    return 0;
}

/* Interface functions -------------------------------------------------------*/
/* description: 喂看门狗
   param:
   return: */
void watchdog_feed(void)
{
    static uint8_t dog = 0;

    /* 防止设备重启不成功, 此时不再喂狗, cpu依然会重启 */
    if (is_system_reboot)
    {
        return;
    }
    
    dog = dog ? 0 : 1;
    GPIO_WATCHDOG(dog);
}

/* description: 数据处理预初始化.
   param:
   return:  (E_NONE)成功,(其他)失败 */
int32_t process_init(void)
{
    int32_t rv = E_NONE;

    /* 创建消息队列. */
    if ((recv_qid = msgget(0x4321, IPC_CREAT | 0666)) == -1)
    {
        log_err(LOG_DEFAULT, "message ERROR at msgget return %s!", safe_strerror(errno));
    }
    
    /* 清空消息队列. */
    msgctl(recv_qid, IPC_RMID, NULL);
    if ((recv_qid = msgget(0x4321, IPC_CREAT | 0666)) == -1)
    {
        log_err(LOG_DEFAULT, "message ERROR at msgget return %s!", safe_strerror(errno));
    }

    /* 初始化局放应用. */
    rv |= pd_main();

    return rv;
}

/* description: 数据处理初始化.
   param:
   return:  (E_NONE)成功,(其他)失败 */
int32_t process_init_after(void)
{
    int32_t rv = E_NONE;

    rv = pd_main_after();

    return rv;
}

/* description: 程序入口函数.
   param:
   return: */
int32_t main(int32_t argc, char **argv)
{
    struct sigaction act;
    
    /* 设置本地化信息为默认值. */
    setlocale(LC_ALL, "");

    /* 必须最前面, 初始化内存管理模块的基本参数. */
    mtype_init_befor();

    /* log初始化 */
    log_open();
    
    log_out(LOG_DEFAULT, LOG_LVL_WARN, "System start!");
    
    /* 设置信号处理的回调函数 */
    act.sa_handler = _signal_handler;
    sigemptyset(&act.sa_mask);
    sigaction(SIGINT, &act, NULL);
    sigaction(SIGSEGV, &act, NULL);
    sigaction(SIGTSTP, &act, NULL);
    
    /* 初始化cli等公共模块. */
    cmd_init();
    thread_m_init();
    mtype_init();
    dbg_init();
    mtimer_init();
    vtysh_init();
    vtycmd_init();
    // gpio_init();
    fifo_init();
    log_handle_init();

    /* 主处理函数预初始化 */
    process_init();
    
    /* 配置恢复命令行启动 */
    vtysh_config_recovery();

    /* 主处理函数初始化 */
    process_init_after();

    /* 启动命令行 */
    vtysh_shell_init();
    vtycmd_cmd_init();

    /* 初始化完成 */
    version_hex = version_str_to_int();
    is_system_init = TRUE;
    
    /* 主循环, 点灯喂狗. */
    for(;;)
    {
        sleep(1);
        start_time++;

        /* 点 RUN 灯, 同步灯 */
        //GPIO_RUN_LED(start_time & 0x1);
        //GPIO_SYNC_LED(!pd_state.sync);
  
        if (0 == (start_time & 0x1f))
        {
            // watchdog_feed();
        }
    }
    
    return 0;
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/
