/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <memory>

#include <binderwrapper/binder_test_base.h>
#include <binderwrapper/stub_binder_wrapper.h>
#include <gtest/gtest.h>

#include "fake_devices.h"
#include "peripheral_manager.h"
#include "peripheralmanager/peripheral_manager_client.h"
#include "peripheralmanager/spi_device.h"
#include "spi_driver_spidev.h"

using android::CharDeviceFactory;
using android::FakeDeviceFactory;
using android::SpiDriverInfo;
using android::SpiDriverInfoBase;
using android::SpiDriverSpiDev;
using android::SpiManager;
using android::PeripheralManager;

// Base class used to test the Spi C API.
// As we rely on static, global managers, we cannot run this tests in parallel.
// Please use -j1 when running theses tests or you may see false negatives.
class SpiTest : public android::BinderTestBase {
 public:
  void SetUp() {
    android::sp<PeripheralManager> pman(new PeripheralManager);
    android::String8 interface_desc(pman->getInterfaceDescriptor());
    binder_wrapper()->SetBinderForService(interface_desc.string(), pman);

    SpiManager* man = SpiManager::GetSpiManager();

    man->GetSpiDevBuses();
    man->RegisterDriver(std::unique_ptr<SpiDriverInfoBase>(
        new SpiDriverInfo<SpiDriverSpiDev, CharDeviceFactory*>(
            &device_factory_)));

    man->RegisterSpiDevBus("SPI_A", 1, 0);
    man->RegisterSpiDevBus("SPI_B", 1, 1);
  }

  void TearDown() { SpiManager::ResetSpiManager(); }

 private:
  FakeDeviceFactory device_factory_;
};

// Test that we can list the available devices.
TEST_F(SpiTest, ListSpiDevices) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();

  int ndev = -1;
  char** devices = BPeripheralManagerClient_listSpiBuses(client, &ndev);

  ASSERT_EQ(2, ndev);
  EXPECT_EQ("SPI_A", std::string(devices[0]));
  EXPECT_EQ("SPI_B", std::string(devices[1]));

  for (int i = 0; i < ndev; i++) {
    free(devices[i]);
  }
  free(devices);

  BPeripheralManagerClient_delete(client);
}

// Test that we can open a device and use the basic functions.
TEST_F(SpiTest, OpenSpiDevice) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();

  BSpiDevice* device = nullptr;
  ASSERT_EQ(0,
            BPeripheralManagerClient_openSpiDevice(client, "SPI_A", &device));
  ASSERT_NE(nullptr, device);

  EXPECT_EQ(0, BSpiDevice_writeByte(device, 0x10));

  std::vector<uint8_t> v = {1, 2, 3, 4};
  EXPECT_EQ(0, BSpiDevice_writeBuffer(device, v.data(), v.size()));

  BSpiDevice_delete(device);
  BPeripheralManagerClient_delete(client);
}

// Test that the transfer function behave correctly.
TEST_F(SpiTest, Transfer) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();

  BSpiDevice* device = nullptr;
  ASSERT_EQ(0,
            BPeripheralManagerClient_openSpiDevice(client, "SPI_A", &device));
  ASSERT_NE(nullptr, device);

  // Passing an empty return pointer is valid.
  std::vector<uint8_t> v = {0, 0, 0, 0};
  uint8_t received[4];
  EXPECT_EQ(0, BSpiDevice_transfer(device, v.data(), nullptr, v.size()));

  // Passing an empty send pointer is invalid.
  EXPECT_EQ(EINVAL, BSpiDevice_transfer(device, nullptr, &received, 4));

  BSpiDevice_delete(device);
  BPeripheralManagerClient_delete(client);
}

// Test that we can configure the device correctly and that we fail cleanly if
// the configuration is incorrect.
TEST_F(SpiTest, SetConfiguration) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();

  BSpiDevice* device = nullptr;
  ASSERT_EQ(0,
            BPeripheralManagerClient_openSpiDevice(client, "SPI_A", &device));
  ASSERT_NE(nullptr, device);

  // We can set the mode and detect an invalid mode.
  EXPECT_EQ(0, BSpiDevice_setMode(device, SPI_MODE0));
  EXPECT_EQ(0, BSpiDevice_setMode(device, SPI_MODE1));
  EXPECT_EQ(0, BSpiDevice_setMode(device, SPI_MODE2));
  EXPECT_EQ(0, BSpiDevice_setMode(device, SPI_MODE3));
  EXPECT_EQ(EINVAL, BSpiDevice_setMode(device, SPI_MODE3 + 1));

  // We can set the bit justification and detect an invalid justification.
  EXPECT_EQ(0, BSpiDevice_setBitJustification(device, SPI_LSB_FIRST));
  EXPECT_EQ(0, BSpiDevice_setBitJustification(device, SPI_MSB_FIRST));
  EXPECT_EQ(EINVAL, BSpiDevice_setBitJustification(device, SPI_MSB_FIRST + 1));

  // We can set the frequency.
  EXPECT_EQ(0, BSpiDevice_setFrequency(device, 100000));

  // We can set the number of bits per word.
  EXPECT_EQ(0, BSpiDevice_setBitsPerWord(device, 16));

  // We can set the delay between transfers.
  EXPECT_EQ(0, BSpiDevice_setDelay(device, 100));

  BSpiDevice_delete(device);
  BPeripheralManagerClient_delete(client);
}

// Test that we fail when trying to open the same device twice.
TEST_F(SpiTest, CantOpenDeviceTwice) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();

  BSpiDevice* device1 = nullptr;
  BSpiDevice* device2 = nullptr;
  BSpiDevice* device3 = nullptr;

  // Can open SPI_A once.
  ASSERT_EQ(0,
            BPeripheralManagerClient_openSpiDevice(client, "SPI_A", &device1));
  ASSERT_NE(nullptr, device1);

  // The device can't be opened a second time because it is busy.
  ASSERT_EQ(EBUSY,
            BPeripheralManagerClient_openSpiDevice(client, "SPI_A", &device2));
  ASSERT_EQ(nullptr, device2);

  // Can open another device.
  ASSERT_EQ(0,
            BPeripheralManagerClient_openSpiDevice(client, "SPI_B", &device3));

  // Once released, we can re-open the device.
  BSpiDevice_delete(device1);
  ASSERT_EQ(0,
            BPeripheralManagerClient_openSpiDevice(client, "SPI_A", &device2));

  BSpiDevice_delete(device2);
  BSpiDevice_delete(device3);
  BPeripheralManagerClient_delete(client);
}

// Test that we fail when trying to open an unknown device.
TEST_F(SpiTest, CantOpenUnknownDevice) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();

  BSpiDevice* device = nullptr;
  ASSERT_EQ(
      ENODEV,
      BPeripheralManagerClient_openSpiDevice(client, "SPI_UNKOWN", &device));
  ASSERT_EQ(nullptr, device);

  BPeripheralManagerClient_delete(client);
}
