// 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 "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "media/midi/midi_manager.h"
#include "media/midi/midi_service.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {
namespace {

using midi::mojom::PortState;

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

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) {}
  ~MidiHostForTesting() override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(MidiHostForTesting);
};

class MidiSessionClientForTesting : public midi::mojom::MidiSessionClient {
 public:
  MidiSessionClientForTesting() = default;
  ~MidiSessionClientForTesting() override = default;

  void AddInputPort(midi::mojom::PortInfoPtr info) override {}
  void AddOutputPort(midi::mojom::PortInfoPtr info) override {}
  void SetInputPortState(uint32_t port, PortState state) override {}
  void SetOutputPortState(uint32_t port, PortState state) override {}
  void SessionStarted(midi::mojom::Result result) override {}
  void AcknowledgeSentData(uint32_t bytes) override {}
  void DataReceived(uint32_t port,
                    const std::vector<uint8_t>& data,
                    base::TimeTicks timestamp) override {}
};

class MidiHostTest : public testing::Test {
 public:
  MidiHostTest() : data_(kNoteOn, kNoteOn + base::size(kNoteOn)), port_id_(0) {
    browser_context_ = std::make_unique<TestBrowserContext>();
    rph_ = std::make_unique<MockRenderProcessHost>(browser_context_.get());
    std::unique_ptr<FakeMidiManagerFactory> factory =
        std::make_unique<FakeMidiManagerFactory>();
    factory_ = factory->GetWeakPtr();
    service_ = std::make_unique<midi::MidiService>(std::move(factory));
    host_ = std::make_unique<MidiHostForTesting>(rph_->GetID(), service_.get());
    midi::mojom::MidiSessionClientPtr ptr;
    midi::mojom::MidiSessionClientRequest request = mojo::MakeRequest(&ptr);
    mojo::MakeStrongBinding(std::make_unique<MidiSessionClientForTesting>(),
                            std::move(request));
    midi::mojom::MidiSessionRequest session_request =
        mojo::MakeRequest(&session_);
    host_->StartSession(std::move(session_request), std::move(ptr));
  }
  ~MidiHostTest() override {
    session_.reset();
    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) {
    host_->SendData(port, data_, base::TimeTicks());
  }

  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();
  }

  int GetNumberOfBadMessages() { return rph_->bad_msg_count(); }

 private:
  TestBrowserThreadBundle thread_bundle_;
  std::unique_ptr<BrowserContext> browser_context_;
  std::unique_ptr<MockRenderProcessHost> rph_;

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

  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());
  EXPECT_EQ(1, GetNumberOfBadMessages());

  // 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 content
