// 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 "services/audio/log_factory_manager.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/memory/ptr_util.h"
#include "base/test/scoped_task_environment.h"
#include "media/mojo/interfaces/audio_logging.mojom.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/audio/traced_service_ref.h"
#include "services/service_manager/public/cpp/service_keepalive.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace audio {

using testing::_;
using testing::SaveArg;

namespace {

class MockAudioLog : public media::mojom::AudioLog {
 public:
  MockAudioLog() {}
  MOCK_METHOD2(OnCreated,
               void(const media::AudioParameters& params,
                    const std::string& device_id));

  MOCK_METHOD0(OnStarted, void());
  MOCK_METHOD0(OnStopped, void());
  MOCK_METHOD0(OnClosed, void());
  MOCK_METHOD0(OnError, void());
  MOCK_METHOD1(OnSetVolume, void(double));
  MOCK_METHOD1(OnProcessingStateChanged, void(const std::string&));
  MOCK_METHOD1(OnLogMessage, void(const std::string&));
};

class MockAudioLogFactory : public media::mojom::AudioLogFactory {
 public:
  MockAudioLogFactory(media::mojom::AudioLogFactoryRequest request,
                      size_t num_mock_logs)
      : binding_(this, std::move(request)) {
    for (size_t i = 0; i < num_mock_logs; ++i)
      mock_logs_.push_back(new MockAudioLog());
  }

  MOCK_METHOD2(MockCreateAudioLog,
               void(media::mojom::AudioLogComponent, int32_t));

  void CreateAudioLog(
      media::mojom::AudioLogComponent component,
      int32_t component_id,
      media::mojom::AudioLogRequest audio_log_request) override {
    MockCreateAudioLog(component, component_id);
    mojo::MakeStrongBinding(base::WrapUnique(mock_logs_[current_mock_log_++]),
                            std::move(audio_log_request));
  }

  MockAudioLog* GetMockLog(size_t index) { return mock_logs_[index]; }

 private:
  mojo::Binding<media::mojom::AudioLogFactory> binding_;
  size_t current_mock_log_ = 0;
  std::vector<MockAudioLog*> mock_logs_;
  DISALLOW_COPY_AND_ASSIGN(MockAudioLogFactory);
};

}  // namespace

class LogFactoryManagerTest
    : public ::testing::Test,
      public service_manager::ServiceKeepalive::Observer {
 public:
  LogFactoryManagerTest() : service_keepalive_(nullptr, base::TimeDelta()) {
    service_keepalive_.AddObserver(this);
  }

 protected:
  MOCK_METHOD0(OnNoServiceRefs, void());

  void CreateLogFactoryManager() {
    log_factory_manager_ = std::make_unique<LogFactoryManager>();
    log_factory_manager_->Bind(
        mojo::MakeRequest(&log_factory_manager_ptr_),
        TracedServiceRef(service_keepalive_.CreateRef(),
                         "audio::LogFactoryManager Binding"));
    EXPECT_FALSE(service_keepalive_.HasNoRefs());
  }

  void DestroyLogFactoryManager() {
    log_factory_manager_ptr_.reset();
    scoped_task_environment_.RunUntilIdle();
    EXPECT_TRUE(service_keepalive_.HasNoRefs());
  }

  // service_manager::ServiceKeepalive::Observer:
  void OnIdleTimeout() override { OnNoServiceRefs(); }

  base::test::ScopedTaskEnvironment scoped_task_environment_;
  mojom::LogFactoryManagerPtr log_factory_manager_ptr_;
  std::unique_ptr<LogFactoryManager> log_factory_manager_;

 private:
  service_manager::ServiceKeepalive service_keepalive_;

  DISALLOW_COPY_AND_ASSIGN(LogFactoryManagerTest);
};

TEST_F(LogFactoryManagerTest, LogFactoryManagerQueuesRequestsAndSetsFactory) {
  EXPECT_CALL(*this, OnNoServiceRefs());
  CreateLogFactoryManager();

  // Create a log before setting the log factory.
  const int kComponentId1 = 1;
  const double kVolume1 = 0.5;
  media::AudioLogFactory* log_factory = log_factory_manager_->GetLogFactory();
  std::unique_ptr<media::AudioLog> log1 = log_factory->CreateAudioLog(
      media::AudioLogFactory::AUDIO_OUTPUT_STREAM, kComponentId1);
  log1->OnStarted();
  log1->OnSetVolume(kVolume1);
  log1->OnStopped();
  log1->OnClosed();

  // Set the factory.
  media::mojom::AudioLogFactoryPtr log_factory_ptr;
  MockAudioLogFactory mock_factory(mojo::MakeRequest(&log_factory_ptr), 2);
  MockAudioLog* mock_log1 = mock_factory.GetMockLog(0);
  testing::InSequence s;

  // Set the factory and expect that queued operations run.
  EXPECT_CALL(mock_factory,
              MockCreateAudioLog(media::mojom::AudioLogComponent::kOutputStream,
                                 kComponentId1));
  EXPECT_CALL(*mock_log1, OnStarted());
  EXPECT_CALL(*mock_log1, OnSetVolume(kVolume1));
  EXPECT_CALL(*mock_log1, OnStopped());
  EXPECT_CALL(*mock_log1, OnClosed());
  log_factory_manager_ptr_->SetLogFactory(std::move(log_factory_ptr));
  scoped_task_environment_.RunUntilIdle();

  // Create another log after the factory is already set.
  const int kComponentId2 = 2;
  const double kVolume2 = 0.1;
  EXPECT_CALL(
      mock_factory,
      MockCreateAudioLog(media::mojom::AudioLogComponent::kInputController,
                         kComponentId2));
  MockAudioLog* mock_log2 = mock_factory.GetMockLog(1);
  EXPECT_CALL(*mock_log2, OnStarted());
  EXPECT_CALL(*mock_log2, OnSetVolume(kVolume2));
  EXPECT_CALL(*mock_log2, OnStopped());
  EXPECT_CALL(*mock_log2, OnClosed());

  std::unique_ptr<media::AudioLog> log2 = log_factory->CreateAudioLog(
      media::AudioLogFactory::AUDIO_INPUT_CONTROLLER, 2);
  log2->OnStarted();
  log2->OnSetVolume(kVolume2);
  log2->OnStopped();
  log2->OnClosed();

  // Ensure all mock objects are released.
  log1.reset();
  log2.reset();
  DestroyLogFactoryManager();
}

}  // namespace audio
