/*
 * 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 "gpio_driver_mock.h"
#include "peripheral_manager.h"
#include "peripheralmanager/gpio.h"
#include "peripheralmanager/peripheral_manager_client.h"

using android::GpioDriverInfo;
using android::GpioDriverInfoBase;
using android::GpioDriverMock;
using android::GpioManager;
using android::PeripheralManager;

// Base class used to test the Gpio 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 GpioTest : 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);

    GpioManager* man = GpioManager::GetGpioManager();
    man->RegisterDriver(std::unique_ptr<GpioDriverInfoBase>(
        new GpioDriverInfo<GpioDriverMock, void*>(nullptr)));

    man->RegisterGpioSysfs("IO1", 1);
    man->RegisterGpioSysfs("IO2", 2);
    man->RegisterGpioSysfs("IO3", 3);
    man->RegisterGpioSysfs("IO4", 4);
    man->RegisterGpioSysfs("IO5", 5);
  }

  void TearDown() { GpioManager::ResetGpioManager(); }
};

// Test that we list the Gpios available correctly.
TEST_F(GpioTest, CanListGpios) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();
  ASSERT_NE(nullptr, client);

  int ngpios;
  char** list = BPeripheralManagerClient_listGpio(client, &ngpios);

  EXPECT_EQ(5, ngpios);
  EXPECT_EQ("IO1", std::string(list[0]));
  EXPECT_EQ("IO2", std::string(list[1]));
  EXPECT_EQ("IO3", std::string(list[2]));
  EXPECT_EQ("IO4", std::string(list[3]));
  EXPECT_EQ("IO5", std::string(list[4]));

  // Free the list.
  for (int i = 0; i < 5; i++) {
    free(list[i]);
  }
  free(list);
}

// Test that we can open a Gpio and act on it.
TEST_F(GpioTest, CanOpenGpio) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();
  ASSERT_NE(nullptr, client);

  BGpio* gpio;
  EXPECT_EQ(0, BPeripheralManagerClient_openGpio(client, "IO1", &gpio));
  ASSERT_NE(nullptr, gpio);

  // Can set the direction. If the direction is invalid, we fail.
  EXPECT_EQ(0, BGpio_setDirection(gpio, DIRECTION_OUT_INITIALLY_HIGH));
  EXPECT_EQ(EINVAL, BGpio_setDirection(gpio, 10));

  // Can set the value.
  EXPECT_EQ(0, BGpio_setValue(gpio, 1));

  // Can set the active type. If the type is unknown, we fail.
  EXPECT_EQ(0, BGpio_setActiveType(gpio, ACTIVE_LOW));
  EXPECT_EQ(EINVAL, BGpio_setActiveType(gpio, 5));

  EXPECT_EQ(0, BGpio_setDirection(gpio, DIRECTION_IN));

  // Can read the value from the Gpio.
  int value;
  EXPECT_EQ(0, BGpio_getValue(gpio, &value));

  // Setting the value returns an error.
  EXPECT_EQ(EREMOTEIO, BGpio_setValue(gpio, 1));

  // Can set the edge type. If the type is unknown, we fail.
  EXPECT_EQ(0, BGpio_setEdgeTriggerType(gpio, RISING_EDGE));
  EXPECT_EQ(EINVAL, BGpio_setEdgeTriggerType(gpio, -1));

  BGpio_delete(gpio);
  BPeripheralManagerClient_delete(client);
}

// Test that openning an unknown Gpio fails.
TEST_F(GpioTest, OpenningUnknownGpioFails) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();
  ASSERT_NE(nullptr, client);

  BGpio* gpio = nullptr;
  EXPECT_EQ(ENODEV,
            BPeripheralManagerClient_openGpio(client, "unknown", &gpio));
  EXPECT_EQ(nullptr, gpio);

  BPeripheralManagerClient_delete(client);
}

// Test that we track ownership correctly (can't open a Gpio twice).
TEST_F(GpioTest, GpioOnlyOpenedOnce) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();
  ASSERT_NE(nullptr, client);

  BGpio* gpio1;
  BGpio* gpio2;
  BGpio* gpio3;

  EXPECT_EQ(0, BPeripheralManagerClient_openGpio(client, "IO1", &gpio1));
  EXPECT_NE(nullptr, gpio1);

  // Can't open the same Gpio.
  EXPECT_EQ(EBUSY, BPeripheralManagerClient_openGpio(client, "IO1", &gpio2));

  // Can open another Gpio.
  EXPECT_EQ(0, BPeripheralManagerClient_openGpio(client, "IO3", &gpio3));

  // Once we delete the struct, the Gpio is released and we can open it.
  BGpio_delete(gpio1);
  EXPECT_EQ(0, BPeripheralManagerClient_openGpio(client, "IO1", &gpio2));

  BGpio_delete(gpio2);
  BGpio_delete(gpio3);
  BPeripheralManagerClient_delete(client);
}
