// 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 "kudu/clock/test/mini_chronyd.h"

#include <ctime>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <gtest/gtest.h>

#include "kudu/clock/test/mini_chronyd_test_util.h"
#include "kudu/util/net/net_util.h"
#include "kudu/util/status.h"
#include "kudu/util/test_macros.h"
#include "kudu/util/test_util.h"

using std::string;
using std::unique_ptr;
using std::vector;

namespace kudu {
namespace clock {

class MiniChronydTest: public KuduTest {
};

// Run chronyd without any reference: neither local reference mode, nor
// reference NTP server present. Such server cannot be a good NTP source
// because its clock is unsynchronized.
TEST_F(MiniChronydTest, UnsynchronizedServer) {
  unique_ptr<MiniChronyd> chrony;
  {
    MiniChronydOptions options;
    options.local = false;
    ASSERT_OK(StartChronydAtAutoReservedPort(std::move(options), &chrony));
  }

  // No client has talked to the NTP server yet.
  {
    MiniChronyd::ServerStats stats;
    ASSERT_OK(chrony->GetServerStats(&stats));
    ASSERT_EQ(0, stats.ntp_packets_received);
  }

  auto s = MiniChronyd::CheckNtpSource({ chrony->address() });
  ASSERT_TRUE(s.IsRuntimeError()) << s.ToString();
  ASSERT_STR_CONTAINS(s.ToString(),
                      "failed measure clock offset from reference NTP servers");

  // Make sure the client has communicated with the server.
  {
    MiniChronyd::ServerStats stats;
    ASSERT_OK(chrony->GetServerStats(&stats));
    ASSERT_LT(0, stats.ntp_packets_received);
  }
}

// This scenario verifies basic functionality of the mini-chronyd wrapper:
// start, stop, manually setting the reference time, etc.
TEST_F(MiniChronydTest, BasicSingleServerInstance) {
  // Start chronyd at the specified port, making sure it's serving requests.
  unique_ptr<MiniChronyd> chrony;
  ASSERT_OK(StartChronydAtAutoReservedPort({}, &chrony));

  // A chronyd that uses the system clock as a reference lock should present
  // itself as reliable NTP server.
  const HostPort ntp_endpoint(chrony->address());
  {
    // Make sure the server opens ports to listen and serve requests
    // from NTP clients.
    auto s = MiniChronyd::CheckNtpSource({ ntp_endpoint });
    ASSERT_TRUE(s.ok()) << s.ToString();
  }

  // Set time manually using chronyc and verify that chronyd tracks the time as
  // expected.
  ASSERT_OK(chrony->SetTime(time(nullptr) - 60));

  // Sanity check: make sure chronyd receives NTP packets which were sent
  // by chronyc and the chronyd running in client-only mode.
  MiniChronyd::ServerStats stats;
  ASSERT_OK(chrony->GetServerStats(&stats));
  ASSERT_LT(0, stats.ntp_packets_received);
  ASSERT_LT(0, stats.cmd_packets_received);
  const auto ntp_packets_received = stats.ntp_packets_received;

  {
    // After setting the clock manually to be simply offset from the reference,
    // chronyd should continue providing a good NTP source for its clients.
    auto s = MiniChronyd::CheckNtpSource({ ntp_endpoint });
    ASSERT_TRUE(s.ok()) << s.ToString();

    // The activity of checking for a reliable NTP source and fetching
    // information on the system clock synchronisation status should generate
    // additional NTP packets which should have been received by the NTP server.
    MiniChronyd::ServerStats stats;
    ASSERT_OK(chrony->GetServerStats(&stats));
    ASSERT_GT(stats.ntp_packets_received, ntp_packets_received);
  }
}

// This scenario runs multiple chronyd and verifies they can co-exist without
// conflicts w.r.t. resources such as port numbers and paths to their
// configuration files, command sockets, and other related files.
TEST_F(MiniChronydTest, BasicMultipleServerInstances) {
  vector<unique_ptr<MiniChronyd>> servers;
  vector<HostPort> ntp_endpoints;
  for (int idx = 0; idx < 5; ++idx) {
    unique_ptr<MiniChronyd> chrony;
    {
      MiniChronydOptions options;
      options.index = idx;
      ASSERT_OK(StartChronydAtAutoReservedPort(std::move(options), &chrony));
    }
    ntp_endpoints.emplace_back(chrony->address());
    servers.emplace_back(std::move(chrony));
  }

  {
    // All chronyd servers that use the system clock as a reference lock should
    // present themselves as a set of NTP servers suitable for synchronisation.
    auto s = MiniChronyd::CheckNtpSource(ntp_endpoints, 10);
    ASSERT_TRUE(s.ok()) << s.ToString();
  }

  // On macOS the same loopback IP address is used for all the NTP servers:
  // they differ only by their port number. However, it seems chronyd
  // doesn't differentiate between them by IP addr + port, only by IP addr.
  // So, it means chronyd run as a client (chronyd -q/-Q) sees all those as
  // the same NTP server, and talks only with the first one (as listed
  // in the configuration file).

  // Sanity check: make sure every server received packets from the client
  // (see the note above regarding running chronyd at the same IP address
  //  but different NTP port number).
  for (auto& server : servers) {
    MiniChronyd::ServerStats stats;
    ASSERT_OK(server->GetServerStats(&stats));
#ifndef __APPLE__
    ASSERT_LT(0, stats.ntp_packets_received);
#endif
    ASSERT_LT(0, stats.cmd_packets_received);
  }

  // Offset the reference time at the servers, so they would have their
  // reference times far from each other. It doesn't matter from which point
  // the servers are offset, but it's important that they are 'far enough'
  // from each other. The idea is to make sure the client does _not_ see these
  // servers as a reliable source for time synchronisation via NTP.
  const auto ref_time = time(nullptr) - 50;
  for (auto i = 0; i < servers.size(); ++i) {
    ASSERT_OK(servers[i]->SetTime(ref_time + i * 10));
  }

#ifndef __APPLE__
  {
    // Now, with contradicting source NTP servers, it should be impossible
    // to synchronize the time.
    auto s = MiniChronyd::CheckNtpSource(ntp_endpoints, 10);
    ASSERT_TRUE(s.IsRuntimeError()) << s.ToString();
    ASSERT_STR_CONTAINS(s.ToString(), "No suitable source for synchronisation");
  }
#endif
}

// This scenario runs multi-tier set of chronyd servers: few servers of
// stratum X and few more servers of stratum X+1, so the latter use the former
// as the source for synchronisation. Both set of servers should be a good clock
// source to serve NTP clients.
TEST_F(MiniChronydTest, MultiTierBasic) {
  vector<unique_ptr<MiniChronyd>> servers_0;
  vector<HostPort> ntp_endpoints_0;
  for (auto idx = 0; idx < 3; ++idx) {
    unique_ptr<MiniChronyd> chrony;
    {
      MiniChronydOptions options;
      options.index = idx;
      ASSERT_OK(StartChronydAtAutoReservedPort(std::move(options), &chrony));
    }
    ntp_endpoints_0.emplace_back(chrony->address());
    servers_0.emplace_back(std::move(chrony));
  }

  vector<unique_ptr<MiniChronyd>> servers_1;
  vector<HostPort> ntp_endpoints_1;
  for (auto idx = 3; idx < 5; ++idx) {
    unique_ptr<MiniChronyd> chrony;
    {
      MiniChronydOptions options;
      options.index = idx;
      options.local = false;
      for (const auto& ref : servers_0) {
        const auto addr = ref->address();
        MiniChronydServerOptions server_options;
        server_options.address = addr.host();
        server_options.port = addr.port();
        options.servers.emplace_back(std::move(server_options));
      }
      ASSERT_OK(StartChronydAtAutoReservedPort(std::move(options), &chrony));
    }
    ntp_endpoints_1.emplace_back(chrony->address());
    servers_1.emplace_back(std::move(chrony));
  }

  {
    // All chronyd servers that use the system clock as a reference lock should
    // present themselves as a set of NTP servers suitable for synchronisation.
    auto s = MiniChronyd::CheckNtpSource(ntp_endpoints_0);
    ASSERT_TRUE(s.ok()) << s.ToString();
  }
  {
    // All chronyd servers that use the above mentioned chronyd servers
    // as reference should be a set of good NTP sources as well.
    auto s = MiniChronyd::CheckNtpSource(ntp_endpoints_1);
    ASSERT_TRUE(s.ok()) << s.ToString();
  }
}

} // namespace clock
} // namespace kudu
