/*
 * 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_i2c_devices.h"
#include "i2c_driver_i2cdev.h"
#include "peripheral_manager.h"
#include "peripheralmanager/i2c_device.h"
#include "peripheralmanager/peripheral_manager_client.h"

using android::CharDeviceFactory;
using android::FakeI2cDeviceFactory;
using android::I2cDriverI2cDev;
using android::I2cDriverInfo;
using android::I2cDriverInfoBase;
using android::I2cManager;
using android::PeripheralManager;

class I2cTest : 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);

    I2cManager* man = I2cManager::GetI2cManager();
    man->RegisterDriver(std::unique_ptr<I2cDriverInfoBase>(
        new I2cDriverInfo<I2cDriverI2cDev, CharDeviceFactory*>(
            &i2c_device_factory_)));

    man->RegisterI2cDevBus("I2C0", 0);
    man->RegisterI2cDevBus("I2C1", 1);
  }

  void TearDown() { I2cManager::ResetI2cManager(); }

 private:
  FakeI2cDeviceFactory i2c_device_factory_;
};

// Test that we can list the I2c buses correctly.
TEST_F(I2cTest, ListI2cBuses) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();

  int nbuses = -1;
  char** devices = BPeripheralManagerClient_listI2cBuses(client, &nbuses);

  ASSERT_EQ(2, nbuses);
  EXPECT_EQ("I2C0", std::string(devices[0]));
  EXPECT_EQ("I2C1", std::string(devices[1]));

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

  BPeripheralManagerClient_delete(client);
}

// Test that we can open a device and perform basic operations.
TEST_F(I2cTest, OpenDevice) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();

  BI2cDevice* device;
  ASSERT_EQ(
      0, BPeripheralManagerClient_openI2cDevice(client, "I2C0", 0x10, &device));

  std::vector<uint8_t> buffer(40, 42);

  uint32_t count = 0;

  // Can write 20 bytes to the device.
  EXPECT_EQ(0, BI2cDevice_write(device, buffer.data(), 20, &count));
  EXPECT_EQ(20, count);

  // Can write bytes and words to specific registers.
  EXPECT_EQ(0, BI2cDevice_writeRegByte(device, 8, 60));
  EXPECT_EQ(0, BI2cDevice_writeRegWord(device, 9, 2000));

  // Can write 20 bytes to a specific register.
  count = 0;
  EXPECT_EQ(0,
            BI2cDevice_writeRegBuffer(device, 10, buffer.data(), 20, &count));
  EXPECT_EQ(20, count);

  uint8_t byte;
  uint16_t word;

  // Can read 20 bytes from the device.
  buffer.assign(40, 0);
  count = 0;
  EXPECT_EQ(0, BI2cDevice_read(device, buffer.data(), 20, &count));
  EXPECT_EQ(20, count);

  // Can read bytes and word from the device.
  EXPECT_EQ(0, BI2cDevice_readRegByte(device, 8, &byte));
  EXPECT_EQ(60, byte);

  EXPECT_EQ(0, BI2cDevice_readRegWord(device, 9, &word));
  EXPECT_EQ(2000, word);

  // Can read 20 bytes from a specific register.
  count = 0;
  buffer.assign(40, 0);
  EXPECT_EQ(0, BI2cDevice_readRegBuffer(device, 10, buffer.data(), 20, &count));
  EXPECT_EQ(20, count);
  for (int i = 0; i < 40; i++) {
    EXPECT_EQ(i < 20 ? 42 : 0, buffer[i]);
  }

  BI2cDevice_delete(device);
  BPeripheralManagerClient_delete(client);
}

// Test that we can't open the same device twice.
TEST_F(I2cTest, CantOpenDeviceTwice) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();

  BI2cDevice* device1 = nullptr;
  BI2cDevice* device2 = nullptr;
  BI2cDevice* device3 = nullptr;
  BI2cDevice* device4 = nullptr;

  // Can open the device once.
  ASSERT_EQ(
      0,
      BPeripheralManagerClient_openI2cDevice(client, "I2C0", 0x10, &device1));
  ASSERT_NE(nullptr, device1);

  // Can open a device on the same address on a different bus.
  ASSERT_EQ(
      0,
      BPeripheralManagerClient_openI2cDevice(client, "I2C1", 0x10, &device2));
  ASSERT_NE(nullptr, device2);

  // Can open another device on the same bus.
  ASSERT_EQ(
      0,
      BPeripheralManagerClient_openI2cDevice(client, "I2C0", 0x13, &device3));
  ASSERT_NE(nullptr, device3);

  // Can't open a device already in use.
  ASSERT_EQ(
      EBUSY,
      BPeripheralManagerClient_openI2cDevice(client, "I2C0", 0x10, &device4));
  ASSERT_EQ(nullptr, device4);

  // After releasing the device, we can re-open it.
  BI2cDevice_delete(device1);
  ASSERT_EQ(
      0,
      BPeripheralManagerClient_openI2cDevice(client, "I2C0", 0x10, &device4));
  ASSERT_NE(nullptr, device4);

  BI2cDevice_delete(device2);
  BI2cDevice_delete(device3);
  BI2cDevice_delete(device4);
  BPeripheralManagerClient_delete(client);
}

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

  BI2cDevice* device = nullptr;
  ASSERT_EQ(
      ENODEV,
      BPeripheralManagerClient_openI2cDevice(client, "I2C5", 0x10, &device));
  ASSERT_EQ(nullptr, device);

  BPeripheralManagerClient_delete(client);
}
