// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/media/audio/lib/clock/real_clock.h"

#include <lib/syslog/cpp/macros.h>
#include <lib/zx/clock.h>
#include <lib/zx/time.h>
#include <zircon/syscalls/clock.h>

#include <string>

#include <gtest/gtest.h>

#include "src/media/audio/lib/clock/clone_mono.h"
#include "src/media/audio/lib/clock/utils.h"

namespace media_audio {
namespace {

constexpr auto kMonotonicDomain = Clock::kMonotonicDomain;
constexpr auto kExternalDomain = Clock::kExternalDomain;

zx::clock NewClock(zx_rights_t rights = ZX_RIGHT_DUPLICATE | ZX_RIGHT_READ | ZX_RIGHT_WRITE) {
  zx::clock clock;
  auto status = zx::clock::create(
      ZX_CLOCK_OPT_AUTO_START | ZX_CLOCK_OPT_MONOTONIC | ZX_CLOCK_OPT_CONTINUOUS, nullptr, &clock);
  FX_CHECK(status == ZX_OK) << "clock.create failed, status is " << status;

  status = clock.replace(rights, &clock);
  FX_CHECK(status == ZX_OK) << "clock.replace failed, status is " << status;

  return clock;
}

TEST(RealClockTest, CreateUnadjustable) {
  const zx_rights_t rights = ZX_RIGHT_DUPLICATE | ZX_RIGHT_READ;
  auto clock = RealClock::Create("clock", NewClock(rights), kMonotonicDomain, false);
  EXPECT_EQ(clock->name(), "clock");
  EXPECT_EQ(clock->domain(), kMonotonicDomain);
  EXPECT_FALSE(clock->adjustable());
}

TEST(RealClockTest, CreateAdjustable) {
  const zx_rights_t rights = ZX_RIGHT_DUPLICATE | ZX_RIGHT_READ | ZX_RIGHT_WRITE;
  auto clock = RealClock::Create("clock", NewClock(rights), kExternalDomain, true);
  EXPECT_EQ(clock->name(), "clock");
  EXPECT_EQ(clock->domain(), kExternalDomain);
  EXPECT_TRUE(clock->adjustable());
}

TEST(RealClockTest, CreateUnadjustableMonotonic) {
  auto clock = RealClock::CreateFromMonotonic("clock", kMonotonicDomain, false);
  EXPECT_EQ(clock->name(), "clock");
  EXPECT_EQ(clock->domain(), kMonotonicDomain);
  EXPECT_FALSE(clock->adjustable());
  EXPECT_TRUE(clock->IdenticalToMonotonicClock());
}

TEST(RealClockTest, CreateAdjustableMonotonic) {
  auto clock = RealClock::CreateFromMonotonic("clock", kExternalDomain, true);
  EXPECT_EQ(clock->name(), "clock");
  EXPECT_EQ(clock->domain(), kExternalDomain);
  EXPECT_TRUE(clock->adjustable());
  EXPECT_TRUE(clock->IdenticalToMonotonicClock());
}

TEST(RealClockTest, Koids) {
  auto c1 = NewClock();
  auto c2 = ::media::audio::clock::DuplicateClock(c1);
  auto c3 = NewClock();

  // Koids should match for duplicated clocks.
  auto clock1 = RealClock::Create("clock1", std::move(c1), kMonotonicDomain, false);
  auto clock2 = RealClock::Create("clock2", std::move(c2), kMonotonicDomain, false);
  auto clock3 = RealClock::Create("clock3", std::move(c3), kMonotonicDomain, false);

  EXPECT_EQ(clock1->koid(), clock2->koid());
  EXPECT_NE(clock1->koid(), clock3->koid());
}

TEST(RealClockTest, SetRate) {
  auto clock = RealClock::Create("clock", NewClock(), kExternalDomain, true);
  auto initial_snapshot = clock->to_clock_mono_snapshot();
  auto r1 = zx::time(0) + zx::hour(1);
  auto r2 = zx::time(0) + zx::hour(2);

  // Initially should be identical to system monotonic.
  EXPECT_TRUE(clock->IdenticalToMonotonicClock());
  EXPECT_EQ(clock->rate_adjustment_ppm(), 0);
  EXPECT_EQ(clock->ReferenceTimeFromMonotonicTime(r1), r1);

  // Set the rate slower.
  clock->SetRate(-1000);
  EXPECT_EQ(clock->rate_adjustment_ppm(), -1000);
  {
    auto snapshot = clock->to_clock_mono_snapshot();
    EXPECT_EQ(initial_snapshot.generation + 1, snapshot.generation);

    auto to_mono = snapshot.to_clock_mono;
    EXPECT_LT(to_mono.reference_delta(), to_mono.subject_delta()) << "rate should be less than 1:1";

    auto m1 = clock->MonotonicTimeFromReferenceTime(r1);
    auto m2 = clock->MonotonicTimeFromReferenceTime(r2);
    EXPECT_LT(r2 - r1, m2 - m1);
    EXPECT_FALSE(clock->IdenticalToMonotonicClock());

    // This might be off by +/-1 due to rounding.
    auto diff = r1 - clock->ReferenceTimeFromMonotonicTime(m1);
    EXPECT_LE(std::abs(diff.get()), 1) << diff.get();
  }

  // Set the rate faster.
  clock->SetRate(1000);
  EXPECT_EQ(clock->rate_adjustment_ppm(), 1000);
  {
    auto snapshot = clock->to_clock_mono_snapshot();
    EXPECT_EQ(initial_snapshot.generation + 2, snapshot.generation);

    auto to_mono = snapshot.to_clock_mono;
    EXPECT_GT(to_mono.reference_delta(), to_mono.subject_delta()) << "rate should be more than 1:1";

    auto m1 = clock->MonotonicTimeFromReferenceTime(r1);
    auto m2 = clock->MonotonicTimeFromReferenceTime(r2);
    EXPECT_GT(r2 - r1, m2 - m1);
    EXPECT_FALSE(clock->IdenticalToMonotonicClock());

    // This might be off by +/-1 due to rounding.
    auto diff = r1 - clock->ReferenceTimeFromMonotonicTime(m1);
    EXPECT_LE(std::abs(diff.get()), 1) << diff.get();
  }
}

}  // namespace
}  // namespace media_audio
