// Copyright 2013 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 "content/browser/media/midi_host.h"

#include <stddef.h>
#include <stdint.h>

#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_task_environment.h"
#include "content/common/media/midi_messages.h"
#include "content/public/test/test_browser_thread.h"
#include "media/midi/midi_manager.h"
#include "media/midi/midi_service.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {
namespace {

using midi::mojom::PortState;

const uint8_t kNoteOn[] = {0x90, 0x3c, 0x7f};
const int kRenderProcessId = 0;

enum MidiEventType {
  DISPATCH_SEND_MIDI_DATA,
};

struct MidiEvent {
  MidiEvent(MidiEventType in_type,
            uint32_t in_port_index,
            const std::vector<uint8_t>& in_data,
            base::TimeTicks in_timestamp)
      : type(in_type),
        port_index(in_port_index),
        data(in_data),
        timestamp(in_timestamp) {}

  MidiEventType type;
  uint32_t port_index;
  std::vector<uint8_t> data;
  base::TimeTicks timestamp;
};

class FakeMidiManager : public midi::MidiManager {
 public:
  explicit FakeMidiManager(midi::MidiService* service)
      : MidiManager(service), weak_factory_(this) {}
  ~FakeMidiManager() override = default;

  base::WeakPtr<FakeMidiManager> GetWeakPtr() {
    return weak_factory_.GetWeakPtr();
  }

  void DispatchSendMidiData(midi::MidiManagerClient* client,
                            uint32_t port_index,
                            const std::vector<uint8_t>& data,
                            base::TimeTicks timestamp) override {
    events_.push_back(MidiEvent(DISPATCH_SEND_MIDI_DATA,
                                port_index,
                                data,
                                timestamp));
  }
  std::vector<MidiEvent> events_;

  base::WeakPtrFactory<FakeMidiManager> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(FakeMidiManager);
};

class FakeMidiManagerFactory : public midi::MidiService::ManagerFactory {
 public:
  FakeMidiManagerFactory() : weak_factory_(this) {}
  ~FakeMidiManagerFactory() override = default;
  std::unique_ptr<midi::MidiManager> Create(
      midi::MidiService* service) override {
    std::unique_ptr<FakeMidiManager> manager =
        std::make_unique<FakeMidiManager>(service);
    manager_ = manager->GetWeakPtr();
    return manager;
  }

  base::WeakPtr<FakeMidiManagerFactory> GetWeakPtr() {
    return weak_factory_.GetWeakPtr();
  }

  base::WeakPtr<FakeMidiManager> GetCreatedManager() { return manager_; }

 private:
  base::WeakPtr<FakeMidiManager> manager_;

  base::WeakPtrFactory<FakeMidiManagerFactory> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(FakeMidiManagerFactory);
};

class MidiHostForTesting : public MidiHost {
 public:
  MidiHostForTesting(int renderer_process_id, midi::MidiService* midi_service)
      : MidiHost(renderer_process_id, midi_service) {}

 private:
  ~MidiHostForTesting() override {}

  // BrowserMessageFilter implementation.
  // Override ShutdownForBadMessage() to do nothing since the original
  // implementation to kill a malicious renderer process causes a check failure
  // in unit tests.
  void ShutdownForBadMessage() override {}

  DISALLOW_COPY_AND_ASSIGN(MidiHostForTesting);
};

class MidiHostTest : public testing::Test {
 public:
  MidiHostTest()
      : io_browser_thread_(BrowserThread::IO,
                           task_environment_.GetMainThreadTaskRunner()),
        data_(kNoteOn, kNoteOn + arraysize(kNoteOn)),
        port_id_(0) {
    std::unique_ptr<FakeMidiManagerFactory> factory =
        std::make_unique<FakeMidiManagerFactory>();
    factory_ = factory->GetWeakPtr();
    service_ = std::make_unique<midi::MidiService>(std::move(factory));
    host_ = new MidiHostForTesting(kRenderProcessId, service_.get());
    host_->OnStartSession();
  }
  ~MidiHostTest() override {
    host_->OnEndSession();
    service_->Shutdown();
    RunLoopUntilIdle();
  }

 protected:
  void AddOutputPort() {
    const std::string id = base::StringPrintf("i-can-%d", port_id_++);
    const std::string manufacturer("yukatan");
    const std::string name("doki-doki-pi-pine");
    const std::string version("3.14159265359");
    PortState state = PortState::CONNECTED;
    midi::mojom::PortInfo info(id, manufacturer, name, version, state);

    host_->AddOutputPort(info);
  }

  void OnSendData(uint32_t port) {
    std::unique_ptr<IPC::Message> message(
        new MidiHostMsg_SendData(port, data_, base::TimeTicks()));
    host_->OnMessageReceived(*message.get());
  }

  size_t GetEventSize() const {
    if (!factory_->GetCreatedManager())
      return 0U;
    return factory_->GetCreatedManager()->events_.size();
  }

  void CheckSendEventAt(size_t at, uint32_t port) {
    base::WeakPtr<FakeMidiManager> manager = factory_->GetCreatedManager();
    ASSERT_TRUE(manager);
    EXPECT_EQ(DISPATCH_SEND_MIDI_DATA, manager->events_[at].type);
    EXPECT_EQ(port, manager->events_[at].port_index);
    EXPECT_EQ(data_, manager->events_[at].data);
    EXPECT_EQ(base::TimeTicks(), manager->events_[at].timestamp);
  }

  void RunLoopUntilIdle() {
    base::RunLoop run_loop;
    run_loop.RunUntilIdle();
  }

 private:
  base::test::ScopedTaskEnvironment task_environment_;
  TestBrowserThread io_browser_thread_;

  std::vector<uint8_t> data_;
  int32_t port_id_;
  base::WeakPtr<FakeMidiManagerFactory> factory_;
  std::unique_ptr<midi::MidiService> service_;
  scoped_refptr<MidiHostForTesting> host_;

  DISALLOW_COPY_AND_ASSIGN(MidiHostTest);
};

}  // namespace

// Test if sending data to out of range port is ignored.
TEST_F(MidiHostTest, OutputPortCheck) {
  // Only one output port is available.
  AddOutputPort();

  // Sending data to port 0 should be delivered.
  uint32_t port0 = 0;
  OnSendData(port0);
  RunLoopUntilIdle();
  EXPECT_EQ(1U, GetEventSize());
  CheckSendEventAt(0, port0);

  // Sending data to port 1 should not be delivered.
  uint32_t port1 = 1;
  OnSendData(port1);
  RunLoopUntilIdle();
  EXPECT_EQ(1U, GetEventSize());

  // Two output ports are available from now on.
  AddOutputPort();

  // Sending data to port 0 and 1 should be delivered now.
  OnSendData(port0);
  OnSendData(port1);
  RunLoopUntilIdle();
  EXPECT_EQ(3U, GetEventSize());
  CheckSendEventAt(1, port0);
  CheckSendEventAt(2, port1);
}

}  // namespace conent
