// Copyright 2018 The Chromium 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 "chrome/browser/media/router/providers/cast/cast_app_discovery_service.h"

#include "base/test/scoped_task_environment.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/test_simple_task_runner.h"
#include "chrome/browser/media/router/test/test_helper.h"
#include "chrome/common/media_router/discovery/media_sink_service_base.h"
#include "chrome/common/media_router/providers/cast/cast_media_source.h"
#include "chrome/common/media_router/test/test_helper.h"
#include "components/cast_channel/cast_test_util.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using cast_channel::GetAppAvailabilityResult;
using testing::_;
using testing::Invoke;

namespace media_router {

class CastAppDiscoveryServiceTest : public testing::Test {
 public:
  CastAppDiscoveryServiceTest()
      : task_runner_(base::MakeRefCounted<base::TestSimpleTaskRunner>()),
        socket_service_(task_runner_),
        message_handler_(&socket_service_),
        app_discovery_service_(
            std::make_unique<CastAppDiscoveryServiceImpl>(&message_handler_,
                                                          &socket_service_,
                                                          &media_sink_service_,
                                                          &clock_)),
        source_a_1_(
            *CastMediaSource::FromMediaSourceId("cast:AAAAAAAA?clientId=1")),
        source_a_2_(
            *CastMediaSource::FromMediaSourceId("cast:AAAAAAAA?clientId=2")),
        source_b_1_(
            *CastMediaSource::FromMediaSourceId("cast:BBBBBBBB?clientId=1")) {
    ON_CALL(socket_service_, GetSocket(_))
        .WillByDefault(testing::Return(&socket_));
    task_runner_->RunPendingTasks();
  }

  ~CastAppDiscoveryServiceTest() override { task_runner_->RunPendingTasks(); }

  MOCK_METHOD2(OnSinkQueryUpdated,
               void(const MediaSource::Id&,
                    const std::vector<MediaSinkInternal>&));

  void AddOrUpdateSink(const MediaSinkInternal& sink) {
    media_sink_service_.AddOrUpdateSink(sink);
  }

  void RemoveSink(const MediaSinkInternal& sink) {
    media_sink_service_.RemoveSink(sink);
  }

  CastAppDiscoveryService::Subscription StartObservingMediaSinksInitially(
      const CastMediaSource& source) {
    auto subscription = app_discovery_service_->StartObservingMediaSinks(
        source,
        base::BindRepeating(&CastAppDiscoveryServiceTest::OnSinkQueryUpdated,
                            base::Unretained(this)));
    task_runner_->RunPendingTasks();
    return subscription;
  }

 protected:
  content::TestBrowserThreadBundle thread_bundle_;
  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
  base::SimpleTestTickClock clock_;
  testing::NiceMock<cast_channel::MockCastSocketService> socket_service_;
  cast_channel::MockCastSocket socket_;
  cast_channel::MockCastMessageHandler message_handler_;
  TestMediaSinkService media_sink_service_;
  std::unique_ptr<CastAppDiscoveryService> app_discovery_service_;
  CastMediaSource source_a_1_;
  CastMediaSource source_a_2_;
  CastMediaSource source_b_1_;

 private:
  DISALLOW_COPY_AND_ASSIGN(CastAppDiscoveryServiceTest);
};

TEST_F(CastAppDiscoveryServiceTest, StartObservingMediaSinks) {
  auto subscription1 = StartObservingMediaSinksInitially(source_a_1_);

  // Adding a sink after app registered causes app availability request to be
  // sent.
  MediaSinkInternal sink1 = CreateCastSink(1);
  cast_channel::GetAppAvailabilityCallback cb;
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "AAAAAAAA", _))
      .WillOnce([&cb](cast_channel::CastSocket*, const std::string&,
                      cast_channel::GetAppAvailabilityCallback callback) {
        cb = std::move(callback);
      });

  AddOrUpdateSink(sink1);

  // Same app ID should not trigger another request.
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, _, _)).Times(0);
  auto subscription2 = app_discovery_service_->StartObservingMediaSinks(
      source_a_2_,
      base::BindRepeating(&CastAppDiscoveryServiceTest::OnSinkQueryUpdated,
                          base::Unretained(this)));

  std::vector<MediaSinkInternal> sinks_1 = {sink1};
  EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_1_.source_id(), sinks_1));
  EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_2_.source_id(), sinks_1));
  std::move(cb).Run("AAAAAAAA", GetAppAvailabilityResult::kAvailable);

  // No more updates for |source_a_1_|.
  subscription1.reset();
  EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_1_.source_id(), _)).Times(0);
  EXPECT_CALL(*this,
              OnSinkQueryUpdated(source_a_2_.source_id(), testing::IsEmpty()));
  RemoveSink(sink1);
}

TEST_F(CastAppDiscoveryServiceTest, ReAddSinkQueryUsesCachedValue) {
  auto subscription1 = StartObservingMediaSinksInitially(source_a_1_);

  // Adding a sink after app registered causes app availability request to be
  // sent.
  MediaSinkInternal sink1 = CreateCastSink(1);
  cast_channel::GetAppAvailabilityCallback cb;
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "AAAAAAAA", _))
      .WillOnce([&cb](cast_channel::CastSocket*, const std::string&,
                      cast_channel::GetAppAvailabilityCallback callback) {
        cb = std::move(callback);
      });

  AddOrUpdateSink(sink1);

  std::vector<MediaSinkInternal> sinks_1 = {sink1};
  EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_1_.source_id(), sinks_1));
  std::move(cb).Run("AAAAAAAA", GetAppAvailabilityResult::kAvailable);

  subscription1.reset();

  // Request not re-sent; cached kAvailable value is used.
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, _, _)).Times(0);
  EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_1_.source_id(), sinks_1));
  subscription1 = StartObservingMediaSinksInitially(source_a_1_);
}

TEST_F(CastAppDiscoveryServiceTest, SinkQueryUpdatedOnSinkUpdate) {
  auto subscription1 = StartObservingMediaSinksInitially(source_a_1_);

  // Adding a sink after app registered causes app availability request to be
  // sent.
  MediaSinkInternal sink1 = CreateCastSink(1);
  cast_channel::GetAppAvailabilityCallback cb;
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "AAAAAAAA", _))
      .WillOnce([&cb](cast_channel::CastSocket*, const std::string&,
                      cast_channel::GetAppAvailabilityCallback callback) {
        cb = std::move(callback);
      });

  AddOrUpdateSink(sink1);

  // Query now includes |sink1|.
  std::vector<MediaSinkInternal> sinks_1 = {sink1};
  EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_1_.source_id(), sinks_1));
  std::move(cb).Run("AAAAAAAA", GetAppAvailabilityResult::kAvailable);

  // Updating |sink1| causes |source_a_1_| query to be updated.
  sink1.sink().set_name("Updated name");
  sinks_1 = {sink1};
  EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_1_.source_id(), sinks_1));
  AddOrUpdateSink(sink1);
}

TEST_F(CastAppDiscoveryServiceTest, Refresh) {
  auto subscription1 = StartObservingMediaSinksInitially(source_a_1_);
  auto subscription2 = StartObservingMediaSinksInitially(source_b_1_);

  MediaSinkInternal sink1 = CreateCastSink(1);
  EXPECT_CALL(*this, OnSinkQueryUpdated(_, _));
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "AAAAAAAA", _))
      .WillOnce([](cast_channel::CastSocket*, const std::string& app_id,
                   cast_channel::GetAppAvailabilityCallback callback) {
        std::move(callback).Run(app_id, GetAppAvailabilityResult::kAvailable);
      });
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "BBBBBBBB", _))
      .WillOnce([](cast_channel::CastSocket*, const std::string& app_id,
                   cast_channel::GetAppAvailabilityCallback callback) {
        std::move(callback).Run(app_id, GetAppAvailabilityResult::kUnknown);
      });
  AddOrUpdateSink(sink1);

  MediaSinkInternal sink2 = CreateCastSink(2);
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "AAAAAAAA", _))
      .WillOnce([](cast_channel::CastSocket*, const std::string& app_id,
                   cast_channel::GetAppAvailabilityCallback callback) {
        std::move(callback).Run(app_id, GetAppAvailabilityResult::kUnavailable);
      });
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "BBBBBBBB", _));
  AddOrUpdateSink(sink2);

  clock_.Advance(base::TimeDelta::FromSeconds(30));

  // Request app availability for app B for both sinks.
  // App A on |sink2| is not requested due to timing threshold.
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "AAAAAAAA", _))
      .Times(0);
  EXPECT_CALL(*this, OnSinkQueryUpdated(_, _)).Times(2);
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "BBBBBBBB", _))
      .Times(2)
      .WillRepeatedly([](cast_channel::CastSocket*, const std::string& app_id,
                         cast_channel::GetAppAvailabilityCallback callback) {
        std::move(callback).Run(app_id, GetAppAvailabilityResult::kAvailable);
      });
  app_discovery_service_->Refresh();

  clock_.Advance(base::TimeDelta::FromSeconds(31));

  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "AAAAAAAA", _));
  app_discovery_service_->Refresh();
}

TEST_F(CastAppDiscoveryServiceTest, StartObservingMediaSinksAfterSinkAdded) {
  // No registered apps.
  MediaSinkInternal sink1 = CreateCastSink(1);
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, _, _)).Times(0);
  AddOrUpdateSink(sink1);

  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "AAAAAAAA", _));
  auto subscription1 = app_discovery_service_->StartObservingMediaSinks(
      source_a_1_,
      base::BindRepeating(&CastAppDiscoveryServiceTest::OnSinkQueryUpdated,
                          base::Unretained(this)));

  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "BBBBBBBB", _));
  auto subscription2 = app_discovery_service_->StartObservingMediaSinks(
      source_b_1_,
      base::BindRepeating(&CastAppDiscoveryServiceTest::OnSinkQueryUpdated,
                          base::Unretained(this)));

  // Adding new sink causes availability requests for 2 apps to be sent to the
  // new sink.
  MediaSinkInternal sink2 = CreateCastSink(2);
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "AAAAAAAA", _));
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "BBBBBBBB", _));
  AddOrUpdateSink(sink2);
}

TEST_F(CastAppDiscoveryServiceTest, StartObservingMediaSinksCachedValue) {
  auto subscription1 = StartObservingMediaSinksInitially(source_a_1_);

  // Adding a sink after app registered causes app availability request to be
  // sent.
  MediaSinkInternal sink1 = CreateCastSink(1);
  cast_channel::GetAppAvailabilityCallback cb;
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "AAAAAAAA", _))
      .WillOnce([&cb](cast_channel::CastSocket*, const std::string&,
                      cast_channel::GetAppAvailabilityCallback callback) {
        cb = std::move(callback);
      });
  AddOrUpdateSink(sink1);

  std::vector<MediaSinkInternal> sinks_1 = {sink1};
  EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_1_.source_id(), sinks_1));
  std::move(cb).Run("AAAAAAAA", GetAppAvailabilityResult::kAvailable);

  // Same app ID should not trigger another request, but it should return
  // cached value.
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, _, _)).Times(0);
  EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_2_.source_id(), sinks_1));
  auto subscription2 = app_discovery_service_->StartObservingMediaSinks(
      source_a_2_,
      base::BindRepeating(&CastAppDiscoveryServiceTest::OnSinkQueryUpdated,
                          base::Unretained(this)));

  // Same source as |source_a_1_|. The callback will be invoked.
  auto source3 = CastMediaSource::FromMediaSourceId("cast:AAAAAAAA?clientId=1");
  ASSERT_TRUE(source3);
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, _, _)).Times(0);
  EXPECT_CALL(*this, OnSinkQueryUpdated(source_a_1_.source_id(), sinks_1));
  auto subscription3 = app_discovery_service_->StartObservingMediaSinks(
      *source3,
      base::BindRepeating(&CastAppDiscoveryServiceTest::OnSinkQueryUpdated,
                          base::Unretained(this)));
}

TEST_F(CastAppDiscoveryServiceTest, AvailabilityUnknownOrUnavailable) {
  auto subscription1 = StartObservingMediaSinksInitially(source_a_1_);

  // Adding a sink after app registered causes app availability request to be
  // sent.
  MediaSinkInternal sink1 = CreateCastSink(1);
  EXPECT_CALL(*this, OnSinkQueryUpdated(_, _)).Times(0);
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "AAAAAAAA", _))
      .WillOnce([](cast_channel::CastSocket*, const std::string&,
                   cast_channel::GetAppAvailabilityCallback callback) {
        std::move(callback).Run("AAAAAAAA", GetAppAvailabilityResult::kUnknown);
      });
  AddOrUpdateSink(sink1);

  // Sink updated and unknown app availability will cause request to be sent
  // again.
  EXPECT_CALL(*this, OnSinkQueryUpdated(_, _)).Times(0);
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "AAAAAAAA", _))
      .WillOnce([](cast_channel::CastSocket*, const std::string&,
                   cast_channel::GetAppAvailabilityCallback callback) {
        std::move(callback).Run("AAAAAAAA",
                                GetAppAvailabilityResult::kUnavailable);
      });
  AddOrUpdateSink(sink1);

  // Known availability -- no request sent.
  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "AAAAAAAA", _))
      .Times(0);
  AddOrUpdateSink(sink1);

  // Removing the sink will also remove previous availability information.
  // Next time sink is added, request will be sent.
  EXPECT_CALL(*this, OnSinkQueryUpdated(_, _)).Times(0);
  RemoveSink(sink1);

  EXPECT_CALL(message_handler_, RequestAppAvailability(_, "AAAAAAAA", _));
  AddOrUpdateSink(sink1);
}

}  // namespace media_router
