// Copyright 2020 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/audio_core/activity_dispatcher.h"

#include <lib/fidl/cpp/binding.h>

#include <gtest/gtest.h>

#include "src/lib/testing/loop_fixture/test_loop_fixture.h"

namespace media::audio {

using RenderActivity = ActivityDispatcherImpl::RenderActivity;
using CaptureActivity = ActivityDispatcherImpl::CaptureActivity;
using RenderUsageVector = std::vector<fuchsia::media::AudioRenderUsage>;
using CaptureUsageVector = std::vector<fuchsia::media::AudioCaptureUsage>;

namespace {
RenderActivity UsageVectorToActivity(
    const std::vector<fuchsia::media::AudioRenderUsage>& usage_vector) {
  RenderActivity activity;
  for (const auto& usage : usage_vector) {
    activity.set(static_cast<int>(usage));
  }
  return activity;
}

CaptureActivity UsageVectorToActivity(
    const std::vector<fuchsia::media::AudioCaptureUsage>& usage_vector) {
  CaptureActivity activity;
  for (const auto& usage : usage_vector) {
    activity.set(static_cast<int>(usage));
  }
  return activity;
}
}  // namespace

typedef ::testing::Types<RenderUsageVector, CaptureUsageVector> UsageVectorTypes;
TYPED_TEST_SUITE(ActivityDispatcherTest, UsageVectorTypes);

template <typename Type>
class ActivityDispatcherTest : public gtest::TestLoopFixture {
 protected:
  fuchsia::media::ActivityReporterPtr GetClient() {
    fuchsia::media::ActivityReporterPtr activity_reporter;
    activity_dispatcher_.GetFidlRequestHandler()(activity_reporter.NewRequest());
    return activity_reporter;
  }

  void SetErrorHandler(fuchsia::media::ActivityReporterPtr& reporter,
                       std::function<void(zx_status_t status)> err) {
    reporter.set_error_handler(err);
  }

  void WatchActivity(fuchsia::media::ActivityReporterPtr& reporter,
                     std::function<void(const Type& v)> cb) {
    WatchActivity<Type>(reporter, cb);
  }

  template <typename UsageVector>
  void WatchActivity(fuchsia::media::ActivityReporterPtr& reporter,
                     std::function<void(const UsageVector& v)> cb);

  template <>
  void WatchActivity<RenderUsageVector>(fuchsia::media::ActivityReporterPtr& reporter,
                                        std::function<void(const RenderUsageVector& v)> cb) {
    reporter->WatchRenderActivity(cb);
  }

  template <>
  void WatchActivity<CaptureUsageVector>(fuchsia::media::ActivityReporterPtr& reporter,
                                         std::function<void(const CaptureUsageVector& v)> cb) {
    reporter->WatchCaptureActivity(cb);
  }

  // Simulates a new set of usages being active.
  void UpdateActivity(const Type& usage_vector) { UpdateActivity<Type>(usage_vector); }

  template <typename UsageVector>
  void UpdateActivity(const UsageVector& usage_vector);

  template <>
  void UpdateActivity<RenderUsageVector>(const RenderUsageVector& usage_vector) {
    activity_dispatcher_.OnRenderActivityChanged(UsageVectorToActivity(usage_vector));
  }

  template <>
  void UpdateActivity<CaptureUsageVector>(const CaptureUsageVector& usage_vector) {
    activity_dispatcher_.OnCaptureActivityChanged(UsageVectorToActivity(usage_vector));
  }

  // Methods to produce templatized usage vectors.
  Type EmptyVector() { return {}; }

  Type SingleVector() { return SingleVector<Type>(); }

  template <typename UsageVector>
  UsageVector SingleVector();

  template <>
  RenderUsageVector SingleVector<RenderUsageVector>() {
    return {fuchsia::media::AudioRenderUsage::BACKGROUND};
  }
  template <>
  CaptureUsageVector SingleVector<CaptureUsageVector>() {
    return {fuchsia::media::AudioCaptureUsage::BACKGROUND};
  }

  Type MultiVector() { return MultiVector<Type>(); }

  template <typename UsageVector>
  UsageVector MultiVector();

  template <>
  RenderUsageVector MultiVector<RenderUsageVector>() {
    return {fuchsia::media::AudioRenderUsage::BACKGROUND,
            fuchsia::media::AudioRenderUsage::SYSTEM_AGENT};
  }
  template <>
  CaptureUsageVector MultiVector<CaptureUsageVector>() {
    return {fuchsia::media::AudioCaptureUsage::BACKGROUND,
            fuchsia::media::AudioCaptureUsage::SYSTEM_AGENT};
  }

 private:
  ActivityDispatcherImpl activity_dispatcher_;
};

TYPED_TEST(ActivityDispatcherTest, FirstWatchReturnsImmediately) {
  fuchsia::media::ActivityReporterPtr activity_reporter = this->GetClient();

  bool called = false;
  this->WatchActivity(activity_reporter, [&](auto v) { called = true; });
  this->RunLoopUntilIdle();
  EXPECT_TRUE(called);
}

TYPED_TEST(ActivityDispatcherTest, SecondWatchHangsWithoutUpdate) {
  fuchsia::media::ActivityReporterPtr activity_reporter = this->GetClient();

  bool first_called = false;
  this->WatchActivity(activity_reporter, [&](auto v) { first_called = true; });
  this->RunLoopUntilIdle();
  EXPECT_TRUE(first_called);

  // Check that the Watch does not return without an update in the activity.
  bool second_called = false;
  this->WatchActivity(activity_reporter, [&](auto v) { second_called = true; });
  this->RunLoopUntilIdle();
  EXPECT_FALSE(second_called);
}

TYPED_TEST(ActivityDispatcherTest, SecondWatchReturnsWithUpdate) {
  fuchsia::media::ActivityReporterPtr activity_reporter = this->GetClient();

  bool first_called = false;
  this->WatchActivity(activity_reporter, [&](auto activity) { first_called = true; });
  this->RunLoopUntilIdle();
  EXPECT_TRUE(first_called);

  bool second_called = false;
  auto actual_usages = this->EmptyVector();
  this->WatchActivity(activity_reporter, [&](auto usages) {
    second_called = true;
    actual_usages = usages;
  });
  this->RunLoopUntilIdle();
  EXPECT_FALSE(second_called);

  auto expected_usages = this->SingleVector();
  this->UpdateActivity(expected_usages);

  // Check that the Watch does return with an update in the activity.
  this->RunLoopUntilIdle();
  EXPECT_TRUE(second_called);
  EXPECT_EQ(expected_usages, actual_usages);
}

TYPED_TEST(ActivityDispatcherTest, WatchReturnsCachedValue) {
  fuchsia::media::ActivityReporterPtr activity_reporter = this->GetClient();

  auto expected_usages = this->SingleVector();
  this->UpdateActivity(expected_usages);
  this->RunLoopUntilIdle();

  bool called = false;
  auto actual_usages = this->EmptyVector();
  this->WatchActivity(activity_reporter, [&](auto usages) {
    called = true;
    actual_usages = usages;
  });
  this->RunLoopUntilIdle();

  EXPECT_TRUE(called);
  EXPECT_EQ(expected_usages, actual_usages);
}

TYPED_TEST(ActivityDispatcherTest, WatchSkipsTransientValue) {
  fuchsia::media::ActivityReporterPtr activity_reporter = this->GetClient();

  bool first_called = false;
  this->WatchActivity(activity_reporter, [&](auto activity) { first_called = true; });
  this->RunLoopUntilIdle();
  EXPECT_TRUE(first_called);

  auto transient_usages = this->SingleVector();
  this->UpdateActivity(transient_usages);
  this->RunLoopUntilIdle();

  auto expected_usages = this->MultiVector();
  this->UpdateActivity(expected_usages);
  this->RunLoopUntilIdle();

  // Check that the Watch returns the latest value and not the transient one.
  bool second_called = false;
  auto actual_usages = this->EmptyVector();
  this->WatchActivity(activity_reporter, [&](auto usages) {
    second_called = true;
    actual_usages = usages;
  });
  this->RunLoopUntilIdle();
  EXPECT_TRUE(second_called);
  EXPECT_EQ(expected_usages, actual_usages);
}

TYPED_TEST(ActivityDispatcherTest, WatchHangsAfterFlap) {
  fuchsia::media::ActivityReporterPtr activity_reporter = this->GetClient();

  bool first_called = false;
  this->WatchActivity(activity_reporter, [&](auto activity) { first_called = true; });
  this->RunLoopUntilIdle();
  EXPECT_TRUE(first_called);

  auto transient_usages = this->SingleVector();
  this->UpdateActivity(transient_usages);
  this->RunLoopUntilIdle();

  auto original_usages = this->EmptyVector();
  this->UpdateActivity(original_usages);
  this->RunLoopUntilIdle();

  // Check that the Watch does not return if original activity is restored before next Watch.
  bool second_called = false;
  this->WatchActivity(activity_reporter, [&](auto usages) { second_called = true; });
  this->RunLoopUntilIdle();
  EXPECT_FALSE(second_called);
}

TYPED_TEST(ActivityDispatcherTest, WatchHangsOnRedundantChange) {
  fuchsia::media::ActivityReporterPtr activity_reporter = this->GetClient();

  bool first_called = false;
  this->WatchActivity(activity_reporter, [&](auto activity) { first_called = true; });
  this->RunLoopUntilIdle();
  EXPECT_TRUE(first_called);

  auto redundant_usages = this->EmptyVector();
  this->UpdateActivity(redundant_usages);
  this->RunLoopUntilIdle();

  // Check that redundant changes are not dispatched.
  bool second_called = false;
  this->WatchActivity(activity_reporter, [&](auto usages) { second_called = true; });
  this->RunLoopUntilIdle();
  EXPECT_FALSE(second_called);
}

TYPED_TEST(ActivityDispatcherTest, MultipleClients) {
  fuchsia::media::ActivityReporterPtr client = this->GetClient();

  // First client gets first activity.
  bool first_called = false;
  this->WatchActivity(client, [&](auto activity) { first_called = true; });
  this->RunLoopUntilIdle();
  EXPECT_TRUE(first_called);

  auto expected_usages = this->SingleVector();
  this->UpdateActivity(expected_usages);
  this->RunLoopUntilIdle();

  // First client gets second activity.
  bool second_called = false;
  auto actual_usages = this->EmptyVector();
  this->WatchActivity(client, [&](auto usages) {
    second_called = true;
    actual_usages = usages;
  });
  this->RunLoopUntilIdle();
  EXPECT_TRUE(second_called);
  EXPECT_EQ(expected_usages, actual_usages);

  fuchsia::media::ActivityReporterPtr second_client = this->GetClient();

  // Second client gets second activty.
  bool third_called = false;
  auto other_actual_usages = this->EmptyVector();
  this->WatchActivity(second_client, [&](auto usages) {
    third_called = true;
    other_actual_usages = usages;
  });
  this->RunLoopUntilIdle();
  EXPECT_TRUE(third_called);
  EXPECT_EQ(expected_usages, other_actual_usages);

  // Both clients get the activity update.
  bool first_client_called = false;
  bool second_client_called = false;
  auto first_client_new_actual_usages = this->EmptyVector();
  auto second_client_new_actual_usages = this->EmptyVector();
  this->WatchActivity(client, [&](auto usages) {
    first_client_called = true;
    first_client_new_actual_usages = usages;
  });
  this->WatchActivity(second_client, [&](auto usages) {
    second_client_called = true;
    second_client_new_actual_usages = usages;
  });
  this->RunLoopUntilIdle();

  auto new_expected_usages = this->MultiVector();
  this->UpdateActivity(new_expected_usages);
  this->RunLoopUntilIdle();

  EXPECT_TRUE(first_client_called);
  EXPECT_TRUE(second_client_called);
  EXPECT_EQ(new_expected_usages, first_client_new_actual_usages);
  EXPECT_EQ(new_expected_usages, second_client_new_actual_usages);
}

TYPED_TEST(ActivityDispatcherTest, TwoHangingGetsTriggerError) {
  fuchsia::media::ActivityReporterPtr activity_reporter = this->GetClient();

  bool client_error_handler_invoked = false;
  zx_status_t client_error_handler_status = ZX_OK;
  this->SetErrorHandler(activity_reporter, [&](zx_status_t status) {
    client_error_handler_status = status;
    client_error_handler_invoked = true;
  });

  bool called = false;
  this->WatchActivity(activity_reporter, [&](auto activity) { called = true; });
  this->RunLoopUntilIdle();

  EXPECT_TRUE(called);

  this->WatchActivity(activity_reporter, [&](auto activity) {});
  this->WatchActivity(activity_reporter, [&](auto activity) {});
  this->RunLoopUntilIdle();

  ASSERT_TRUE(client_error_handler_invoked);
  EXPECT_EQ(client_error_handler_status, ZX_ERR_PEER_CLOSED);
}

}  // namespace media::audio
