// Copyright 2017 The Chromium OS 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 <memory>
#include <string>
#include <utility>

#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <brillo/daemons/daemon.h>
#include <brillo/test_helpers.h>
#include <gtest/gtest.h>

#include "midis/tests/test_helper.h"
#include "midis/udev_handler_mock.h"

using ::testing::_;
using ::testing::Return;

namespace midis {

namespace {

const char kFakeName1[] = "Sample MIDI Device - 1";
const char kFakeManufacturer1[] = "Foo";
const uint32_t kFakeSysNum1 = 2;
const char kFakeDname1[] = "midiC2D0";
const uint32_t kFakeDevNum1 = 0;
const uint32_t kFakeSubdevs1 = 1;
const uint32_t kFakeFlags1 = 7;

const char kFakeName2[] = "Sample MIDI Device - 2";
const char kFakeManufacturer2[] = "Bar";
const uint32_t kFakeSysNum2 = 3;
const char kFakeDname2[] = "midiC3D1";
const uint32_t kFakeDevNum2 = 1;
const uint32_t kFakeSubdevs2 = 2;
const uint32_t kFakeFlags2 = 6;

const char kBlankDname[] = "";

}  // namespace

class UdevHandlerTest : public ::testing::Test {
 public:
  UdevHandlerTest() : udev_handler_mock_(new UdevHandlerMock()) {}

 protected:
  void SetUp() override {
    message_loop_.SetAsCurrent();
    info1_ = std::make_unique<snd_rawmidi_info>();
    memset(info1_.get(), 0, sizeof(snd_rawmidi_info));
    strncpy(reinterpret_cast<char*>(info1_->name), kFakeName1,
            sizeof(kFakeName1));
    info1_->card = kFakeSysNum1;
    info1_->device = kFakeDevNum1;
    info1_->subdevices_count = kFakeSubdevs1;
    info1_->flags = kFakeFlags1;

    info2_ = std::make_unique<snd_rawmidi_info>();
    memset(info2_.get(), 0, sizeof(snd_rawmidi_info));
    strncpy(reinterpret_cast<char*>(info2_->name), kFakeName2,
            sizeof(kFakeName2));
    info2_->card = kFakeSysNum2;
    info2_->device = kFakeDevNum2;
    info2_->subdevices_count = kFakeSubdevs2;
    info2_->flags = kFakeFlags2;

    // Create fake dev nod files
    CreateNewTempDirectory(base::FilePath::StringType(), &temp_fp_);
    if (temp_fp_.empty()) {
      LOG(ERROR) << "Unable to create temporary directory.";
      return;
    }

    base::FilePath dev_path = CreateFakeTempSubDir(temp_fp_, "dev/snd");
    if (dev_path.value() == "") {
      LOG(ERROR) << "Unable to fake dev/snd directory.";
      return;
    }

    base::FilePath dev_node_path =
        CreateDevNodeFileName(dev_path, kFakeSysNum1, kFakeDevNum1);
    int ret = base::WriteFile(dev_node_path, nullptr, 0);
    if (ret == -1) {
      LOG(ERROR) << "Unabled to create fake devnode.";
      return;
    }

    dev_node_path = CreateDevNodeFileName(dev_path, kFakeSysNum2, kFakeDevNum2);
    ret = base::WriteFile(dev_node_path, nullptr, 0);
    if (ret == -1) {
      LOG(ERROR) << "Unabled to create fake devnode.";
      return;
    }
  }

  void TearDown() override { base::DeleteFile(temp_fp_, true); }

  std::unique_ptr<UdevHandlerMock> udev_handler_mock_;
  std::unique_ptr<snd_rawmidi_info> info1_;
  std::unique_ptr<snd_rawmidi_info> info2_;
  base::FilePath temp_fp_;

 private:
  brillo::BaseMessageLoop message_loop_;
};

// Check whether Device gets created successfully.
TEST_F(UdevHandlerTest, CreateDevicePositive) {
  EXPECT_CALL(*udev_handler_mock_, GetMidiDeviceDnameMock(_))
      .WillOnce(Return(kFakeDname1))
      .WillOnce(Return(kFakeDname2));
  EXPECT_CALL(*udev_handler_mock_, GetDeviceInfoMock(_))
      .WillOnce(Return(info1_.release()))
      .WillOnce(Return(info2_.release()));
  EXPECT_CALL(*udev_handler_mock_, ExtractManufacturerStringMock(_, _))
      .WillOnce(Return(kFakeManufacturer1))
      .WillOnce(Return(kFakeManufacturer2));

  ASSERT_FALSE(temp_fp_.empty());

  Device::SetBaseDirForTesting(temp_fp_);
  // Usually, we need to get a reference to a device, but we have mocked
  // the functions that rely on the reference, so it's not necessary.
  // CreateDevice actually needs a udev_device reference, but since we
  // are mocking the internal calls that use it, we can bass a nullptr here
  auto device = udev_handler_mock_->CreateDevice(nullptr);
  uint32_t device_id =
      udev_handler_mock_->GenerateDeviceId(kFakeSysNum1, kFakeDevNum1);
  EXPECT_THAT(device, DeviceMatcher(device_id, kFakeName1, kFakeManufacturer1));

  device = udev_handler_mock_->CreateDevice(nullptr);
  device_id = udev_handler_mock_->GenerateDeviceId(kFakeSysNum2, kFakeDevNum2);
  EXPECT_THAT(device, DeviceMatcher(device_id, kFakeName2, kFakeManufacturer2));
}

// Check behaviour when GetMidiDeviceName and GetDeviceInfo returns nullptr
TEST_F(UdevHandlerTest, CreateDeviceNegative1) {
  EXPECT_CALL(*udev_handler_mock_, GetMidiDeviceDnameMock(_))
      .WillOnce(Return(kBlankDname))
      .WillOnce(Return(kFakeDname1));
  EXPECT_CALL(*udev_handler_mock_, GetDeviceInfoMock(_))
      .WillOnce(Return(nullptr));

  auto device = udev_handler_mock_->CreateDevice(nullptr);
  EXPECT_EQ(device.get(), nullptr);

  device = udev_handler_mock_->CreateDevice(nullptr);
  EXPECT_EQ(device.get(), nullptr);
}

}  // namespace midis
