/* SPDX-License-Identifier: LGPL-2.1+ */

#include <errno.h>
#include <math.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <resolv.h>
#include <stdlib.h>
#include <sys/timerfd.h>
#include <sys/timex.h>
#include <sys/types.h>
#include <linux/rtc.h>
#include <sys/ioctl.h>

#include "log.h"
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
#include "clock-util.h"
#include "fd-util.h"
#include "fs-util.h"
#include "main-func.h"
#include "process-util.h"
#include "signal-util.h"
#include "user-util.h"
#include <unistd.h>

static int run(int argc, char *argv[]) {
        bool rtc_local_time = false;
        int r;
        usec_t n;
        struct timespec ts_sys;
        struct timespec ts_hw;
        struct tm tm_now;

        log_set_facility(LOG_SYSLOG);
        log_setup();

        umask(0022);

        assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);

        if (clock_is_localtime(NULL) > 0) {
                rtc_local_time = true;
        } else {
               rtc_local_time = false;
        }

        n = now(CLOCK_REALTIME);
        timespec_store(&ts_sys, n);
        r = clock_get_hwclock(&tm_now);
        if (r < 0) {
                log_debug_errno(r, "Failed to get hardware clock, ignoring: %m");
        } else {
                if (rtc_local_time)
                        ts_hw.tv_sec = mktime(&tm_now);
                else
                        ts_hw.tv_sec = timegm(&tm_now);

                log_info("hw time: %ld \nsys time:%ld\n", ts_hw.tv_sec, ts_sys.tv_sec);
                if (labs(ts_hw.tv_sec - ts_sys.tv_sec) >= 2) {
                        n = now(CLOCK_REALTIME);
                        timespec_store(&ts_sys, n);
                        if (rtc_local_time) {
                                localtime_r(&ts_sys.tv_sec, &tm_now);
                                log_info("sys time:%s (local)", asctime(&tm_now));
                        } else {
                                gmtime_r(&ts_sys.tv_sec, &tm_now);
                                log_info("sys time:%s (utc)", asctime(&tm_now));
                        }

                        r = clock_set_hwclock(&tm_now);
                        if (r < 0) {
                                log_debug_errno(r, "Failed to update hardware clock, ignoring: %m");
                        } else {
                                log_info("set rtc time success: %s", asctime(&tm_now));
                        }
                } else {
                        log_info("rtc time already sync");
                }
        }
        return 0;
}

DEFINE_MAIN_FUNCTION(run);