// Copyright 2017 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 "media/mojo/services/mojo_audio_input_stream.h"

#include <utility>

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/run_loop.h"
#include "base/sync_socket.h"
#include "base/test/task_environment.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

namespace {

const double kNewVolume = 0.618;
// Not actually used, but sent from the AudioInputDelegate.
const int kStreamId = 0;
const int kShmemSize = 100;
// const bool kInitiallyMuted = true;
const bool kInitiallyNotMuted = true;

using testing::_;
using testing::Mock;
using testing::NotNull;
using testing::Return;
using testing::SaveArg;
using testing::StrictMock;
using testing::Test;
using AudioInputStream = mojom::AudioInputStream;

class TestCancelableSyncSocket : public base::CancelableSyncSocket {
 public:
  TestCancelableSyncSocket() = default;

  void ExpectOwnershipTransfer() { expect_ownership_transfer_ = true; }

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

  ~TestCancelableSyncSocket() override {
    // When the handle is sent over mojo, mojo takes ownership over it and
    // closes it. We have to make sure we do not also retain the handle in the
    // sync socket, as the sync socket closes the handle on destruction.
    if (expect_ownership_transfer_)
      EXPECT_FALSE(IsValid());
  }

 private:
  bool expect_ownership_transfer_ = false;
};

class MockDelegate : public AudioInputDelegate {
 public:
  MockDelegate() = default;
  ~MockDelegate() override = default;

  MOCK_METHOD0(GetStreamId, int());
  MOCK_METHOD0(OnRecordStream, void());
  MOCK_METHOD1(OnSetVolume, void(double));
  MOCK_METHOD1(OnSetOutputDeviceForAec, void(const std::string&));
};

class MockDelegateFactory {
 public:
  void PrepareDelegateForCreation(
      std::unique_ptr<AudioInputDelegate> delegate) {
    ASSERT_EQ(nullptr, delegate_);
    delegate_.swap(delegate);
  }

  std::unique_ptr<AudioInputDelegate> CreateDelegate(
      AudioInputDelegate::EventHandler* handler) {
    MockCreateDelegate(handler);
    EXPECT_NE(nullptr, delegate_);
    return std::move(delegate_);
  }

  MOCK_METHOD1(MockCreateDelegate, void(AudioInputDelegate::EventHandler*));

 private:
  std::unique_ptr<AudioInputDelegate> delegate_;
};

class MockDeleter {
 public:
  MOCK_METHOD0(Finished, void());
};

class MockClient : public mojom::AudioInputStreamClient {
 public:
  MockClient() = default;

  void Initialized(mojom::ReadOnlyAudioDataPipePtr data_pipe,
                   bool initially_muted) {
    ASSERT_TRUE(data_pipe->shared_memory.IsValid());
    ASSERT_TRUE(data_pipe->socket.is_valid());

    socket_ = std::make_unique<base::CancelableSyncSocket>(
        data_pipe->socket.TakePlatformFile());
    EXPECT_TRUE(socket_->IsValid());

    region_ = std::move(data_pipe->shared_memory);
    EXPECT_TRUE(region_.IsValid());

    GotNotification(initially_muted);
  }

  MOCK_METHOD1(GotNotification, void(bool initially_muted));

  MOCK_METHOD1(OnMutedStateChanged, void(bool));

  MOCK_METHOD1(OnError, void(mojom::InputStreamErrorCode));

 private:
  base::ReadOnlySharedMemoryRegion region_;
  std::unique_ptr<base::CancelableSyncSocket> socket_;

  DISALLOW_COPY_AND_ASSIGN(MockClient);
};

std::unique_ptr<AudioInputDelegate> CreateNoDelegate(
    AudioInputDelegate::EventHandler* event_handler) {
  return nullptr;
}

void NotCalled(mojom::ReadOnlyAudioDataPipePtr data_pipe,
               bool initially_muted) {
  EXPECT_TRUE(false) << "The StreamCreated callback was called despite the "
                        "test expecting it not to.";
}

}  // namespace

class MojoAudioInputStreamTest : public Test {
 public:
  MojoAudioInputStreamTest()
      : foreign_socket_(std::make_unique<TestCancelableSyncSocket>()),
        client_receiver_(&client_) {}

  mojo::Remote<mojom::AudioInputStream> CreateAudioInput() {
    mojo::Remote<mojom::AudioInputStream> stream;
    ExpectDelegateCreation();
    impl_ = std::make_unique<MojoAudioInputStream>(
        stream.BindNewPipeAndPassReceiver(),
        client_receiver_.BindNewPipeAndPassRemote(),
        base::BindOnce(&MockDelegateFactory::CreateDelegate,
                       base::Unretained(&mock_delegate_factory_)),
        base::BindOnce(&MockClient::Initialized, base::Unretained(&client_)),
        base::BindOnce(&MockDeleter::Finished, base::Unretained(&deleter_)));
    EXPECT_TRUE(stream.is_bound());
    return stream;
  }

 protected:
  void ExpectDelegateCreation() {
    delegate_ = new StrictMock<MockDelegate>();
    mock_delegate_factory_.PrepareDelegateForCreation(
        base::WrapUnique(delegate_));
    EXPECT_TRUE(
        base::CancelableSyncSocket::CreatePair(&local_, foreign_socket_.get()));
    mem_ = base::ReadOnlySharedMemoryRegion::Create(kShmemSize).region;
    EXPECT_TRUE(mem_.IsValid());
    EXPECT_CALL(mock_delegate_factory_, MockCreateDelegate(NotNull()))
        .WillOnce(SaveArg<0>(&delegate_event_handler_));
  }

  base::test::SingleThreadTaskEnvironment task_environment_;
  base::CancelableSyncSocket local_;
  std::unique_ptr<TestCancelableSyncSocket> foreign_socket_;
  base::ReadOnlySharedMemoryRegion mem_;
  StrictMock<MockDelegate>* delegate_ = nullptr;
  AudioInputDelegate::EventHandler* delegate_event_handler_ = nullptr;
  StrictMock<MockDelegateFactory> mock_delegate_factory_;
  StrictMock<MockDeleter> deleter_;
  StrictMock<MockClient> client_;
  mojo::Receiver<media::mojom::AudioInputStreamClient> client_receiver_;
  std::unique_ptr<MojoAudioInputStream> impl_;

  DISALLOW_COPY_AND_ASSIGN(MojoAudioInputStreamTest);
};

TEST_F(MojoAudioInputStreamTest, NoDelegate_SignalsError) {
  bool deleter_called = false;
  EXPECT_CALL(client_, OnError(mojom::InputStreamErrorCode::kUnknown));
  mojo::Remote<mojom::AudioInputStream> stream_remote;
  MojoAudioInputStream stream(
      stream_remote.BindNewPipeAndPassReceiver(),
      client_receiver_.BindNewPipeAndPassRemote(),
      base::BindOnce(&CreateNoDelegate), base::BindOnce(&NotCalled),
      base::BindOnce([](bool* p) { *p = true; }, &deleter_called));
  EXPECT_FALSE(deleter_called)
      << "Stream shouldn't call the deleter from its constructor.";
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(deleter_called);
}

TEST_F(MojoAudioInputStreamTest, Record_Records) {
  auto audio_input = CreateAudioInput();
  EXPECT_CALL(*delegate_, OnRecordStream());

  audio_input->Record();
  base::RunLoop().RunUntilIdle();
}

TEST_F(MojoAudioInputStreamTest, SetVolume_SetsVolume) {
  auto audio_input = CreateAudioInput();
  EXPECT_CALL(*delegate_, OnSetVolume(kNewVolume));

  audio_input->SetVolume(kNewVolume);
  base::RunLoop().RunUntilIdle();
}

TEST_F(MojoAudioInputStreamTest, DestructWithCallPending_Safe) {
  auto audio_input = CreateAudioInput();
  EXPECT_CALL(client_, GotNotification(kInitiallyNotMuted));
  base::RunLoop().RunUntilIdle();

  ASSERT_NE(nullptr, delegate_event_handler_);
  foreign_socket_->ExpectOwnershipTransfer();
  delegate_event_handler_->OnStreamCreated(kStreamId, std::move(mem_),
                                           std::move(foreign_socket_),
                                           kInitiallyNotMuted);
  audio_input->Record();
  impl_.reset();
  base::RunLoop().RunUntilIdle();
}

TEST_F(MojoAudioInputStreamTest, Created_NotifiesClient) {
  auto audio_input = CreateAudioInput();
  base::RunLoop().RunUntilIdle();

  EXPECT_CALL(client_, GotNotification(kInitiallyNotMuted));

  ASSERT_NE(nullptr, delegate_event_handler_);
  foreign_socket_->ExpectOwnershipTransfer();
  delegate_event_handler_->OnStreamCreated(kStreamId, std::move(mem_),
                                           std::move(foreign_socket_),
                                           kInitiallyNotMuted);

  base::RunLoop().RunUntilIdle();
}

TEST_F(MojoAudioInputStreamTest, SetVolumeTooLarge_Error) {
  auto audio_input = CreateAudioInput();
  EXPECT_CALL(deleter_, Finished());
  EXPECT_CALL(client_, OnError(mojom::InputStreamErrorCode::kUnknown));

  audio_input->SetVolume(15);
  base::RunLoop().RunUntilIdle();
  Mock::VerifyAndClear(&deleter_);
}

TEST_F(MojoAudioInputStreamTest, SetVolumeNegative_Error) {
  auto audio_input = CreateAudioInput();
  EXPECT_CALL(deleter_, Finished());
  EXPECT_CALL(client_, OnError(mojom::InputStreamErrorCode::kUnknown));

  audio_input->SetVolume(-0.5);
  base::RunLoop().RunUntilIdle();
  Mock::VerifyAndClear(&deleter_);
}

TEST_F(MojoAudioInputStreamTest, DelegateErrorBeforeCreated_PropagatesError) {
  auto audio_input = CreateAudioInput();
  EXPECT_CALL(deleter_, Finished());
  EXPECT_CALL(client_, OnError(mojom::InputStreamErrorCode::kUnknown));

  ASSERT_NE(nullptr, delegate_event_handler_);
  delegate_event_handler_->OnStreamError(kStreamId);

  base::RunLoop().RunUntilIdle();
  Mock::VerifyAndClear(&deleter_);
}

TEST_F(MojoAudioInputStreamTest, DelegateErrorAfterCreated_PropagatesError) {
  auto audio_input = CreateAudioInput();
  EXPECT_CALL(client_, GotNotification(kInitiallyNotMuted));
  EXPECT_CALL(deleter_, Finished());
  EXPECT_CALL(client_, OnError(mojom::InputStreamErrorCode::kUnknown));
  base::RunLoop().RunUntilIdle();

  ASSERT_NE(nullptr, delegate_event_handler_);
  foreign_socket_->ExpectOwnershipTransfer();
  delegate_event_handler_->OnStreamCreated(kStreamId, std::move(mem_),
                                           std::move(foreign_socket_),
                                           kInitiallyNotMuted);
  delegate_event_handler_->OnStreamError(kStreamId);

  base::RunLoop().RunUntilIdle();
  Mock::VerifyAndClear(&deleter_);
}

TEST_F(MojoAudioInputStreamTest, RemoteEndGone_Error) {
  auto audio_input = CreateAudioInput();
  EXPECT_CALL(deleter_, Finished());
  audio_input.reset();
  base::RunLoop().RunUntilIdle();
  Mock::VerifyAndClear(&deleter_);
}

}  // namespace media
