/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "os_test_priv.h"

#define OTTC_MAX_ENTRIES    16

struct ottc_entry {
    struct os_timeval prev_tv;
    struct os_timeval cur_tv;
    struct os_timezone prev_tz;
    struct os_timezone cur_tz;
    bool newly_synced;
    void *arg;
};

/** Holds records of listener callback calls. */
static struct ottc_entry ottc_entries[OTTC_MAX_ENTRIES];
static int ottc_num_entries;

static void
ottc_time_change_cb(const struct os_time_change_info *info, void *arg)
{
    struct ottc_entry *entry;

    TEST_ASSERT_FATAL(ottc_num_entries < OTTC_MAX_ENTRIES);
    entry = &ottc_entries[ottc_num_entries++];

    entry->prev_tv = *info->tci_prev_tv;
    entry->cur_tv = *info->tci_cur_tv;
    entry->prev_tz = *info->tci_prev_tz;
    entry->cur_tz = *info->tci_cur_tz;
    entry->newly_synced = info->tci_newly_synced;
    entry->arg = arg;
}

TEST_CASE(os_time_test_change)
{
    struct os_timezone tz1;
    struct os_timezone tz2;
    struct os_timeval tv1;
    struct os_timeval tv2;
    int rc;
    int i;

    struct os_time_change_listener listeners[3] = {
        [0] = {
            .tcl_fn = ottc_time_change_cb,
            .tcl_arg = (void *)(uintptr_t)0,
        },
        [1] = {
            .tcl_fn = ottc_time_change_cb,
            .tcl_arg = (void *)(uintptr_t)1,
        },
        [2] = {
            .tcl_fn = ottc_time_change_cb,
            .tcl_arg = (void *)(uintptr_t)2,
        },
    };

    /* Register one listener. */
    os_time_change_listen(&listeners[0]);

    /* Set time; ensure single listener called. */
    tv1.tv_sec = 123;
    tv1.tv_usec = 456;
    tz1.tz_minuteswest = 555;
    tz1.tz_dsttime = 666;

    rc = os_settimeofday(&tv1, &tz1);
    TEST_ASSERT_FATAL(rc == 0);

    TEST_ASSERT_FATAL(ottc_num_entries == 1);
    TEST_ASSERT(memcmp(&ottc_entries[0].cur_tv, &tv1, sizeof tv1) == 0);
    TEST_ASSERT(memcmp(&ottc_entries[0].cur_tz, &tz1, sizeof tz1) == 0);
    TEST_ASSERT(ottc_entries[0].newly_synced);
    TEST_ASSERT(ottc_entries[0].arg == (void *)(uintptr_t)0);

    /* Register two more listeners. */
    os_time_change_listen(&listeners[1]);
    os_time_change_listen(&listeners[2]);

    /* Set time; ensure all three listeners called. */
    tv2.tv_sec = 234;
    tv2.tv_usec = 567;
    tz2.tz_minuteswest = 777;
    tz2.tz_dsttime = 888;

    rc = os_settimeofday(&tv2, &tz2);
    TEST_ASSERT_FATAL(rc == 0);

    TEST_ASSERT_FATAL(ottc_num_entries == 4);
    for (i = 1; i < 4; i++) {
        TEST_ASSERT(memcmp(&ottc_entries[i].cur_tv, &tv2, sizeof tv2) == 0);
        TEST_ASSERT(memcmp(&ottc_entries[i].cur_tz, &tz2, sizeof tz2) == 0);
        TEST_ASSERT(memcmp(&ottc_entries[i].prev_tv, &tv2, sizeof tv2) == 0);
        TEST_ASSERT(memcmp(&ottc_entries[i].prev_tz, &tz2, sizeof tz2) == 0);
        TEST_ASSERT(!ottc_entries[i].newly_synced);
        TEST_ASSERT(ottc_entries[i].arg == (void *)(uintptr_t)(i - 1));
    }

    /* Remove all three listeners. */
    for (i = 0; i < 3; i++) {
        rc = os_time_change_remove(&listeners[i]);
        TEST_ASSERT(rc == 0);
    }

    /* Set time; ensure no listeners called. */
    tv2.tv_sec = 345;
    tv2.tv_usec = 678;
    tz2.tz_minuteswest = 888;
    tz2.tz_dsttime = 999;

    rc = os_settimeofday(&tv2, &tz2);
    TEST_ASSERT_FATAL(rc == 0);

    TEST_ASSERT_FATAL(ottc_num_entries == 4);
}
