// Copyright 2015 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 <stdint.h>

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "media/base/cdm_config.h"
#include "media/base/mock_filters.h"
#include "media/base/test_helpers.h"
#include "media/media_buildflags.h"
#include "media/mojo/buildflags.h"
#include "media/mojo/clients/mojo_decryptor.h"
#include "media/mojo/clients/mojo_demuxer_stream_impl.h"
#include "media/mojo/common/media_type_converters.h"
#include "media/mojo/mojom/content_decryption_module.mojom.h"
#include "media/mojo/mojom/decryptor.mojom.h"
#include "media/mojo/mojom/interface_factory.mojom.h"
#include "media/mojo/mojom/media_service.mojom.h"
#include "media/mojo/mojom/renderer.mojom.h"
#include "media/mojo/services/media_service_factory.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace media {

namespace {

using testing::_;
using testing::DoAll;
using testing::Invoke;
using testing::InvokeWithoutArgs;
using testing::NiceMock;
using testing::SaveArg;
using testing::StrictMock;
using testing::WithArg;

MATCHER_P(MatchesResult, success, "") {
  return arg->success == success;
}

#if BUILDFLAG(ENABLE_MOJO_CDM) && !defined(OS_ANDROID)
const char kClearKeyKeySystem[] = "org.w3.clearkey";
const char kInvalidKeySystem[] = "invalid.key.system";
#endif

class MockRendererClient : public mojom::RendererClient {
 public:
  MockRendererClient() = default;

  MockRendererClient(const MockRendererClient&) = delete;
  MockRendererClient& operator=(const MockRendererClient&) = delete;

  ~MockRendererClient() override = default;

  // mojom::RendererClient implementation.
  MOCK_METHOD3(OnTimeUpdate,
               void(base::TimeDelta time,
                    base::TimeDelta max_time,
                    base::TimeTicks capture_time));
  MOCK_METHOD2(OnBufferingStateChange,
               void(BufferingState state, BufferingStateChangeReason reason));
  MOCK_METHOD0(OnEnded, void());
  MOCK_METHOD1(OnError, void(const Status& status));
  MOCK_METHOD1(OnVideoOpacityChange, void(bool opaque));
  MOCK_METHOD1(OnAudioConfigChange, void(const AudioDecoderConfig&));
  MOCK_METHOD1(OnVideoConfigChange, void(const VideoDecoderConfig&));
  MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size& size));
  MOCK_METHOD1(OnStatisticsUpdate,
               void(const media::PipelineStatistics& stats));
  MOCK_METHOD1(OnWaiting, void(WaitingReason));
  MOCK_METHOD1(OnDurationChange, void(base::TimeDelta duration));
  MOCK_METHOD1(OnRemotePlayStateChange, void(MediaStatus::State state));
};

ACTION_P(QuitLoop, run_loop) {
  base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                                run_loop->QuitClosure());
}

// Tests MediaService using TestMojoMediaClient, which supports CDM creation
// using DefaultCdmFactory (only supports Clear Key key system), and Renderer
// creation using DefaultRendererFactory that always create media::RendererImpl.
class MediaServiceTest : public testing::Test {
 public:
  MediaServiceTest()
      : renderer_client_receiver_(&renderer_client_),
        video_stream_(DemuxerStream::VIDEO) {}

  MediaServiceTest(const MediaServiceTest&) = delete;
  MediaServiceTest& operator=(const MediaServiceTest&) = delete;

  ~MediaServiceTest() override = default;

  void SetUp() override {
    mojo::PendingRemote<mojom::FrameInterfaceFactory> frame_interfaces;
    ignore_result(frame_interfaces.InitWithNewPipeAndPassReceiver());

    media_service_impl_ = CreateMediaServiceForTesting(
        media_service_.BindNewPipeAndPassReceiver());
    media_service_.set_idle_handler(
        base::TimeDelta(),
        base::BindRepeating(&MediaServiceTest::OnMediaServiceIdle,
                            base::Unretained(this)));
    media_service_->CreateInterfaceFactory(
        interface_factory_.BindNewPipeAndPassReceiver(),
        std::move(frame_interfaces));
  }

  MOCK_METHOD0(OnCdmConnectionError, void());

  void InitializeCdm(const std::string& key_system, bool expected_result) {
    interface_factory_->CreateCdm(
        key_system, CdmConfig(),
        base::BindOnce(&MediaServiceTest::OnCdmCreated, base::Unretained(this),
                       expected_result));
    // Run this to idle to complete the CreateCdm call.
    task_environment_.RunUntilIdle();
  }

  MOCK_METHOD1(OnRendererInitialized, void(bool));

  void InitializeRenderer(const VideoDecoderConfig& video_config,
                          bool expected_result) {
    base::RunLoop run_loop;
    interface_factory_->CreateDefaultRenderer(
        std::string(), renderer_.BindNewPipeAndPassReceiver());

    video_stream_.set_video_decoder_config(video_config);

    mojo::PendingRemote<mojom::DemuxerStream> video_stream_proxy;
    mojo_video_stream_ = std::make_unique<MojoDemuxerStreamImpl>(
        &video_stream_, video_stream_proxy.InitWithNewPipeAndPassReceiver());

    mojo::PendingAssociatedRemote<mojom::RendererClient> client_remote;
    renderer_client_receiver_.Bind(
        client_remote.InitWithNewEndpointAndPassReceiver());

    std::vector<mojo::PendingRemote<mojom::DemuxerStream>> streams;
    streams.push_back(std::move(video_stream_proxy));

    EXPECT_CALL(*this, OnRendererInitialized(expected_result))
        .WillOnce(QuitLoop(&run_loop));
    renderer_->Initialize(
        std::move(client_remote), std::move(streams), nullptr,
        base::BindOnce(&MediaServiceTest::OnRendererInitialized,
                       base::Unretained(this)));
    run_loop.Run();
  }

  MOCK_METHOD0(OnMediaServiceIdle, void());

 protected:
  void OnCdmCreated(bool expected_result,
                    mojo::PendingRemote<mojom::ContentDecryptionModule> remote,
                    media::mojom::CdmContextPtr cdm_context,
                    const std::string& error_message) {
    if (!expected_result) {
      EXPECT_FALSE(remote);
      EXPECT_FALSE(cdm_context);
      EXPECT_TRUE(!error_message.empty());
      return;
    }
    EXPECT_TRUE(remote);
    EXPECT_TRUE(error_message.empty());
    cdm_.Bind(std::move(remote));
    cdm_.set_disconnect_handler(base::BindOnce(
        &MediaServiceTest::OnCdmConnectionError, base::Unretained(this)));
  }
  base::test::TaskEnvironment task_environment_;

  mojo::Remote<mojom::MediaService> media_service_;
  mojo::Remote<mojom::InterfaceFactory> interface_factory_;
  mojo::Remote<mojom::ContentDecryptionModule> cdm_;
  mojo::Remote<mojom::Renderer> renderer_;

  std::unique_ptr<MediaService> media_service_impl_;

  NiceMock<MockRendererClient> renderer_client_;
  mojo::AssociatedReceiver<mojom::RendererClient> renderer_client_receiver_;

  StrictMock<MockDemuxerStream> video_stream_;
  std::unique_ptr<MojoDemuxerStreamImpl> mojo_video_stream_;
};

}  // namespace

// Note: base::RunLoop::RunUntilIdle() does not work well in these tests because
// even when the loop is idle, we may still have pending events in the pipe.
// - If you have an InterfacePtr hosted by the service in the service process,
//   you can use InterfacePtr::FlushForTesting(). Note that this doesn't drain
//   the task runner in the test process and doesn't cover all negative cases.
// - If you expect a callback on an InterfacePtr call or connection error, use
//   base::RunLoop::Run() and QuitLoop().

// TODO(crbug.com/829233): Enable these tests on Android.
#if BUILDFLAG(ENABLE_MOJO_CDM) && !defined(OS_ANDROID)
TEST_F(MediaServiceTest, InitializeCdm_Success) {
  InitializeCdm(kClearKeyKeySystem, true);
}

TEST_F(MediaServiceTest, InitializeCdm_InvalidKeySystem) {
  InitializeCdm(kInvalidKeySystem, false);
}
#endif  // BUILDFLAG(ENABLE_MOJO_CDM) && !defined(OS_ANDROID)

#if BUILDFLAG(ENABLE_MOJO_RENDERER)
TEST_F(MediaServiceTest, InitializeRenderer) {
  InitializeRenderer(TestVideoConfig::Normal(), true);
}
#endif  // BUILDFLAG(ENABLE_MOJO_RENDERER)

TEST_F(MediaServiceTest, InterfaceFactoryPreventsIdling) {
  // The service should not idle during this operation.
  interface_factory_.FlushForTesting();

  // Disconnecting InterfaceFactory will cause the service to idle since there
  // are no media components hosted and so no other interfaces should be
  // connected.
  base::RunLoop run_loop;
  EXPECT_CALL(*this, OnMediaServiceIdle()).WillOnce(QuitLoop(&run_loop));
  interface_factory_.reset();
  run_loop.Run();
}

#if (BUILDFLAG(ENABLE_MOJO_CDM) && !defined(OS_ANDROID)) || \
    BUILDFLAG(ENABLE_MOJO_RENDERER)
// MediaService stays alive as long as there are InterfaceFactory impls, which
// are then deferred destroyed until no media components (e.g. CDM or Renderer)
// are hosted.
TEST_F(MediaServiceTest, Idling) {
#if BUILDFLAG(ENABLE_MOJO_CDM) && !defined(OS_ANDROID)
  InitializeCdm(kClearKeyKeySystem, true);
#endif

#if BUILDFLAG(ENABLE_MOJO_RENDERER)
  InitializeRenderer(TestVideoConfig::Normal(), true);
#endif

  // Disconnecting CDM and Renderer services doesn't terminate MediaService
  // since |interface_factory_| is still alive.
  cdm_.reset();
  renderer_.reset();
  interface_factory_.FlushForTesting();

  // Disconnecting InterfaceFactory will cause the service to idle since no
  // other interfaces are connected.
  base::RunLoop run_loop;
  EXPECT_CALL(*this, OnMediaServiceIdle()).WillOnce(QuitLoop(&run_loop));
  interface_factory_.reset();
  run_loop.Run();
}

TEST_F(MediaServiceTest, MoreIdling) {
#if BUILDFLAG(ENABLE_MOJO_CDM) && !defined(OS_ANDROID)
  InitializeCdm(kClearKeyKeySystem, true);
#endif

#if BUILDFLAG(ENABLE_MOJO_RENDERER)
  InitializeRenderer(TestVideoConfig::Normal(), true);
#endif

  ASSERT_TRUE(cdm_ || renderer_);

  // Disconnecting InterfaceFactory should not terminate the MediaService since
  // there are still media components (CDM or Renderer) hosted.
  interface_factory_.reset();
  if (cdm_)
    cdm_.FlushForTesting();
  else if (renderer_)
    renderer_.FlushForTesting();
  else
    NOTREACHED();

  // Disconnecting CDM and Renderer will cause the service to idle since no
  // other interfaces are connected.
  base::RunLoop run_loop;
  EXPECT_CALL(*this, OnMediaServiceIdle()).WillOnce(QuitLoop(&run_loop));
  cdm_.reset();
  renderer_.reset();
  run_loop.Run();
}
#endif  // (BUILDFLAG(ENABLE_MOJO_CDM) && !defined(OS_ANDROID)) ||
        //  BUILDFLAG(ENABLE_MOJO_RENDERER)

}  // namespace media
