/*
 **********************************************************************
 * Copyright (C) Miroslav Lichvar  2016, 2021
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 **********************************************************************
 */

#include <config.h>
#include "test.h"

#ifdef FEAT_NTP

#include <conf.h>
#include <cmdparse.h>
#include <nameserv_async.h>
#include <ntp_core.h>
#include <ntp_io.h>

static char *requested_name = NULL;
static DNS_NameResolveHandler resolve_handler = NULL;
static void *resolve_handler_arg = NULL;

#define DNS_Name2IPAddressAsync(name, handler, arg) \
  requested_name = (name), \
  resolve_handler = (handler), \
  resolve_handler_arg = (arg)
#define NCR_ChangeRemoteAddress(inst, remote_addr, ntp_only) \
  change_remote_address(inst, remote_addr, ntp_only)
#define NCR_ProcessRxKnown(remote_addr, local_addr, ts, msg, len) (random() % 2)
#define NIO_IsServerConnectable(addr) (random() % 2)

static void change_remote_address(NCR_Instance inst, NTP_Remote_Address *remote_addr,
                                  int ntp_only);

#include <ntp_sources.c>

#undef NCR_ChangeRemoteAddress

static void
resolve_random_address(DNS_Status status, int rand_bits)
{
  IPAddr ip_addrs[DNS_MAX_ADDRESSES];
  int i, n_addrs;

  TEST_CHECK(requested_name);
  requested_name = NULL;

  if (status == DNS_Success) {
    n_addrs = random() % DNS_MAX_ADDRESSES + 1;
    for (i = 0; i < n_addrs; i++)
      TST_GetRandomAddress(&ip_addrs[i], IPADDR_UNSPEC, rand_bits);
  } else {
    n_addrs = 0;
  }

  (resolve_handler)(status, n_addrs, ip_addrs, resolve_handler_arg);
}

static int
update_random_address(NTP_Remote_Address *addr, int rand_bits)
{
  NTP_Remote_Address new_addr;
  NSR_Status status;

  TST_GetRandomAddress(&new_addr.ip_addr, IPADDR_UNSPEC, rand_bits);
  new_addr.port = random() % 1024;

  status = NSR_UpdateSourceNtpAddress(addr, &new_addr);
  if (status == NSR_InvalidAF) {
    TEST_CHECK(!UTI_IsIPReal(&addr->ip_addr));
  } else {
    TEST_CHECK(status == NSR_Success || status == NSR_AlreadyInUse);
  }

  return status == NSR_Success;
}

static void
change_remote_address(NCR_Instance inst, NTP_Remote_Address *remote_addr, int ntp_only)
{
  int update = !ntp_only && random() % 4 == 0, update_pos = random() % 2, r = 0;

  TEST_CHECK(record_lock);

  if (update && update_pos == 0)
    r = update_random_address(remote_addr, 4);

  NCR_ChangeRemoteAddress(inst, remote_addr, ntp_only);

  if (update && update_pos == 1)
    r = update_random_address(remote_addr, 4);

  if (r)
    TEST_CHECK(UTI_IsIPReal(&saved_address_update.old_address.ip_addr));
}

void
test_unit(void)
{
  char source_line[] = "127.0.0.1 offline", conf[] = "port 0", name[64];
  int i, j, k, slot, found, pool, prev_n;
  uint32_t hash = 0, conf_id;
  NTP_Remote_Address addrs[256], addr;
  NTP_Local_Address local_addr;
  NTP_Local_Timestamp local_ts;
  struct UnresolvedSource *us;
  RPT_ActivityReport report;
  CPS_NTP_Source source;
  NSR_Status status;
  NTP_Packet msg;

  CNF_Initialise(0, 0);
  CNF_ParseLine(NULL, 1, conf);

  PRV_Initialise();
  LCL_Initialise();
  TST_RegisterDummyDrivers();
  SCH_Initialise();
  SRC_Initialise();
  NIO_Initialise();
  NCR_Initialise();
  REF_Initialise();
  NSR_Initialise();

  CPS_ParseNTPSourceAdd(source_line, &source);

  TEST_CHECK(n_sources == 0);

  for (i = 0; i < 6; i++) {
    TEST_CHECK(ARR_GetSize(records) == 1);

    DEBUG_LOG("collision mod %u", 1U << i);

    for (j = 0; j < sizeof (addrs) / sizeof (addrs[0]); j++) {
      while (1) {
        do {
          TST_GetRandomAddress(&addrs[j].ip_addr, IPADDR_UNSPEC, -1);
        } while (UTI_IPToHash(&addrs[j].ip_addr) % (1U << i) != hash % (1U << i));

        for (k = 0; k < j; k++)
          if (UTI_CompareIPs(&addrs[k].ip_addr, &addrs[j].ip_addr, NULL) == 0)
            break;
        if (k == j)
          break;
      }

      addrs[j].port = random() % 1024;

      if (!j)
        hash = UTI_IPToHash(&addrs[j].ip_addr);

      DEBUG_LOG("adding source %s hash %"PRIu32, UTI_IPToString(&addrs[j].ip_addr),
                UTI_IPToHash(&addrs[j].ip_addr) % (1U << i));

      status = NSR_AddSource(&addrs[j], random() % 2 ? NTP_SERVER : NTP_PEER,
                             &source.params, NULL);
      TEST_CHECK(status == NSR_Success);
      TEST_CHECK(n_sources == j + 1);

      TEST_CHECK(strcmp(NSR_GetName(&addrs[j].ip_addr), UTI_IPToString(&addrs[j].ip_addr)) == 0);

      for (k = 0; k <= j; k++) {
        addr = addrs[k];
        found = find_slot2(&addr, &slot);
        TEST_CHECK(found == 2);
        TEST_CHECK(!UTI_CompareIPs(&get_record(slot)->remote_addr->ip_addr,
                                   &addr.ip_addr, NULL));
        addr.port++;
        found = find_slot2(&addr, &slot);
        TEST_CHECK(found == 1);
        TEST_CHECK(!UTI_CompareIPs(&get_record(slot)->remote_addr->ip_addr,
                                   &addr.ip_addr, NULL));
      }

      status = NSR_AddSource(&addrs[j], NTP_SERVER, &source.params, &conf_id);
      TEST_CHECK(status == NSR_AlreadyInUse);
    }

    for (j = 0; j < sizeof (addrs) / sizeof (addrs[0]); j++) {
      DEBUG_LOG("removing source %s", UTI_IPToString(&addrs[j].ip_addr));
      NSR_RemoveSource(&addrs[j].ip_addr);

      for (k = 0; k < sizeof (addrs) / sizeof (addrs[0]); k++) {
        found = find_slot2(&addrs[k], &slot);
        TEST_CHECK(found == (k <= j ? 0 : 2));
      }
    }
  }

  TEST_CHECK(n_sources == 0);

  status = NSR_AddSourceByName("a b", 0, 0, 0, &source.params, &conf_id);
  TEST_CHECK(status == NSR_InvalidName);

  local_addr.ip_addr.family = IPADDR_INET4;
  local_addr.ip_addr.addr.in4 = 0;
  local_addr.if_index = -1;
  local_addr.sock_fd = 0;
  memset(&local_ts, 0, sizeof (local_ts));

  for (i = 0; i < 500; i++) {
    for (j = 0; j < 20; j++) {
      snprintf(name, sizeof (name), "ntp%d.example.net", (int)(random() % 10));
      pool = random() % 2;
      prev_n = n_sources;

      DEBUG_LOG("%d/%d adding source %s pool=%d", i, j, name, pool);
      status = NSR_AddSourceByName(name, 0, pool, random() % 2 ? NTP_SERVER : NTP_PEER,
                                   &source.params, &conf_id);
      TEST_CHECK(status == NSR_UnresolvedName);

      TEST_CHECK(n_sources == prev_n + (pool ? source.params.max_sources * 2 : 1));
      TEST_CHECK(unresolved_sources);

      for (us = unresolved_sources; us->next; us = us->next)
        ;
      TEST_CHECK(strcmp(us->name, name) == 0);
      if (pool) {
        TEST_CHECK(us->address.ip_addr.family == IPADDR_UNSPEC && us->pool_id >= 0);
      } else {
        TEST_CHECK(strcmp(NSR_GetName(&us->address.ip_addr), name) == 0);
        TEST_CHECK(find_slot2(&us->address, &slot) == 2);
      }

      if (random() % 2) {
        if (!resolving_id || random() % 2) {
          NSR_ResolveSources();
        } else {
          SCH_RemoveTimeout(resolving_id);
          resolve_sources_timeout(NULL);
          TEST_CHECK(resolving_id == 0);
          TEST_CHECK(requested_name);
        }

        TEST_CHECK(!!unresolved_sources == (resolving_id != 0) || requested_name);
      }

      while (requested_name && random() % 2) {
        TEST_CHECK(resolving_source);
        TEST_CHECK(strcmp(requested_name, resolving_source->name) == 0);
        TEST_CHECK(!record_lock);

        switch (random() % 3) {
          case 0:
            resolve_random_address(DNS_Success, 4);
            break;
          case 1:
            resolve_random_address(DNS_TryAgain, 0);
            break;
          case 2:
            resolve_random_address(DNS_Failure, 0);
            break;
        }
      }

      while (random() % 8 > 0) {
        slot = random() % ARR_GetSize(records);
        if (!get_record(slot)->remote_addr)
          continue;

        switch (random() % 5) {
          case 0:
            msg.lvm = NTP_LVM(0, NTP_VERSION, random() % 2 ? MODE_CLIENT : MODE_SERVER);
            NSR_ProcessTx(get_record(slot)->remote_addr, &local_addr,
                          &local_ts, &msg, 0);
            break;
          case 1:
            msg.lvm = NTP_LVM(0, NTP_VERSION, random() % 2 ? MODE_CLIENT : MODE_SERVER);
            NSR_ProcessRx(get_record(slot)->remote_addr, &local_addr,
                          &local_ts, &msg, 0);
            break;
          case 2:
            NSR_HandleBadSource(&get_record(slot)->remote_addr->ip_addr);
            break;
          case 3:
            NSR_SetConnectivity(NULL, &get_record(slot)->remote_addr->ip_addr, SRC_OFFLINE);
            break;
          case 4:
            update_random_address(get_record(slot)->remote_addr, 4);
            TEST_CHECK(!UTI_IsIPReal(&saved_address_update.old_address.ip_addr));
            break;
        }

        TEST_CHECK(!record_lock);
      }

      NSR_GetActivityReport(&report);
      TEST_CHECK(report.online == 0);
      TEST_CHECK(report.offline >= 0);
      TEST_CHECK(report.burst_online == 0);
      TEST_CHECK(report.burst_offline == 0);
      TEST_CHECK(report.unresolved >= 0);

      if (random() % 4 == 0) {
        NSR_RemoveSourcesById(conf_id);
        TEST_CHECK(n_sources <= prev_n);
      } else if (random() % 8 == 0) {
        NSR_RefreshAddresses();
        TEST_CHECK(unresolved_sources);
      }
    }

    NSR_RemoveAllSources();
    TEST_CHECK(n_sources == 0);

    for (j = 0; j < ARR_GetSize(pools); j++) {
      TEST_CHECK(get_pool(j)->sources == 0);
      TEST_CHECK(get_pool(j)->unresolved_sources == 0);
      TEST_CHECK(get_pool(j)->confirmed_sources == 0);
      TEST_CHECK(get_pool(j)->max_sources == 0);
    }

    while (requested_name) {
      TEST_CHECK(resolving_source);
      resolve_random_address(random() % 2 ? DNS_Success : DNS_TryAgain, 4);
    }

    if (unresolved_sources && resolving_id == 0)
      NSR_ResolveSources();

    TEST_CHECK(!!unresolved_sources == (resolving_id != 0));

    if (resolving_id) {
      SCH_RemoveTimeout(resolving_id);
      resolve_sources_timeout(NULL);
    }

    TEST_CHECK(resolving_id == 0);
    TEST_CHECK(!requested_name);
    TEST_CHECK(!unresolved_sources);
  }

  NSR_Finalise();
  REF_Finalise();
  NCR_Finalise();
  NIO_Finalise();
  SRC_Finalise();
  SCH_Finalise();
  LCL_Finalise();
  PRV_Finalise();
  CNF_Finalise();
  HSH_Finalise();
}

#else
void
test_unit(void)
{
  TEST_REQUIRE(0);
}
#endif
