// Copyright 2021 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/connectivity/bluetooth/core/bt-host/public/pw_bluetooth_sapphire/internal/host/common/retire_log.h"

#include <algorithm>
#include <numeric>
#include <random>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

namespace bt::internal {
namespace {

// Retire 101 entries where the fields in the range [starting_value,
// starting_value + 100]
void Retire101Elements(RetireLog& retire_log, int starting_value = 0) {
  std::vector<int> values(101);
  std::iota(values.begin(), values.end(), starting_value);
  constexpr int kSeed = 4;
  std::shuffle(values.begin(), values.end(), std::default_random_engine(kSeed));
  for (auto value : values) {
    retire_log.Retire(value, std::chrono::milliseconds(value));
  }
}

TEST(RetireLogDeathTest, InitializationLimits) {
  ASSERT_DEATH_IF_SUPPORTED({ RetireLog retire_log(0, 100); }, "min_depth");
  ASSERT_DEATH_IF_SUPPORTED(
      { RetireLog retire_log(101, 100); }, "min_depth.*max_depth");
  ASSERT_DEATH_IF_SUPPORTED(
      { RetireLog retire_log(1, size_t{1} << 60); }, "max_depth");
}

TEST(RetireLogDeathTest, ComputeQuantileLimits) {
  RetireLog retire_log(1, 100);
  retire_log.Retire(1, std::chrono::seconds(1));
  ASSERT_DEATH_IF_SUPPORTED(
      {
        [[maybe_unused]] auto _ =
            retire_log.ComputeByteCountQuantiles(std::array{-1.});
      },
      "0");
  ASSERT_DEATH_IF_SUPPORTED(
      {
        [[maybe_unused]] auto _ =
            retire_log.ComputeByteCountQuantiles(std::array{2.});
      },
      "1");
}

TEST(RetireLogTest, QuantileCallBeforeRetiringYieldsNothing) {
  RetireLog retire_log(1, 100);
  EXPECT_EQ(0U, retire_log.depth());
  auto result = retire_log.ComputeAgeQuantiles(std::array{.5});
  EXPECT_FALSE(result.has_value());
}

TEST(RetireLogTest, QuantileCallsAfterDepthOneYieldsTheResult) {
  RetireLog retire_log(1, 100);
  constexpr pw::chrono::SystemClock::duration kTestDuration =
      std::chrono::milliseconds(10);
  retire_log.Retire(0, kTestDuration);
  auto result = retire_log.ComputeAgeQuantiles(std::array{.5});
  ASSERT_TRUE(result.has_value());
  EXPECT_THAT(*result, testing::Each(testing::Eq(kTestDuration)));
}

TEST(RetireLogTest, ComputeQuantiles) {
  RetireLog retire_log(1, 101);
  Retire101Elements(retire_log);
  auto result = retire_log.ComputeByteCountQuantiles(
      std::array{0., .001, .5, .754, .99, 1.});
  ASSERT_TRUE(result.has_value());

  // Cutting at extremes yields the min and max entries while cutting in the
  // middle yields the median. Cutting between entry values yields the nearest
  // (by distribution) logged value.
  EXPECT_THAT(*result, testing::ElementsAre(0, 0, 50, 76, 99, 100));
}

TEST(RetireLogTest, ComputeQuantilesExactBoundaryIsHighBiased) {
  RetireLog retire_log(2, 2);
  retire_log.Retire(0, {});
  retire_log.Retire(1, {});
  auto result = retire_log.ComputeByteCountQuantiles(std::array{.5});
  ASSERT_TRUE(result.has_value());

  // Cutting at exactly between two entries yields the higher sample
  EXPECT_THAT(*result, testing::ElementsAre(1));
}

TEST(RetireLogTest, ComputeQuantilesOutOfOrderPartitions) {
  RetireLog retire_log(1, 101);
  Retire101Elements(retire_log);
  auto result = retire_log.ComputeByteCountQuantiles(std::array{.75, .25, .5});
  ASSERT_TRUE(result.has_value());
  EXPECT_THAT(*result, testing::ElementsAre(75, 25, 50));
}

// Check that cutting at the same point more than once works
TEST(RetireLogTest, ComputeSameQuantileTwice) {
  RetireLog retire_log(1, 101);
  Retire101Elements(retire_log);
  auto result =
      retire_log.ComputeByteCountQuantiles(std::array{0., 0., 1., 1.});
  ASSERT_TRUE(result.has_value());
  EXPECT_THAT(*result, testing::ElementsAre(0, 0, 100, 100));
}

TEST(RetireLogTest, RetiringPastMaxDepthReplacesPreviousEntries) {
  RetireLog retire_log(1, 101);
  Retire101Elements(retire_log, /*starting_value=*/0);
  Retire101Elements(retire_log, /*starting_value=*/10);
  EXPECT_EQ(101U, retire_log.depth());
  auto result = retire_log.ComputeByteCountQuantiles(std::array{0., .5, 1.});
  ASSERT_TRUE(result.has_value());
  EXPECT_THAT(*result, testing::ElementsAre(10, 60, 110));
}

}  // namespace
}  // namespace bt::internal
