/*
 * 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 <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <binderwrapper/binder_test_base.h>
#include <binderwrapper/stub_binder_wrapper.h>
#include <gtest/gtest.h>

#include "led_driver_sysfs.h"
#include "led_manager.h"
#include "peripheral_manager.h"
#include "peripheralmanager/led.h"
#include "peripheralmanager/peripheral_manager_client.h"

using android::LedDriverInfo;
using android::LedDriverInfoBase;
using android::LedDriverSysfs;
using android::LedManager;
using android::PeripheralManager;

class LedTest : public android::BinderTestBase {
 public:
  void SetUp() {
    CHECK(dir_.CreateUniqueTempDir());

    CreateLed("led1", 255, 0);
    CreateLed("led2", 1000, 0);

    led_path_prefix_ = dir_.path().value() + "/";

    // Initialize the peripheral manager with the stub binder wrapper.
    android::sp<PeripheralManager> pman(new PeripheralManager);
    android::String8 interface_desc(pman->getInterfaceDescriptor());
    binder_wrapper()->SetBinderForService(interface_desc.string(), pman);

    LedManager* man = LedManager::GetLedManager();

    // Register the testing version of the LED driver and the fake LEDs.
    man->RegisterDriver(std::unique_ptr<LedDriverInfoBase>(
        new LedDriverInfo<LedDriverSysfs, std::string*>(&led_path_prefix_)));

    man->RegisterLedSysfs("LED1", "led1");
    man->RegisterLedSysfs("LED2", "led2");
  }

  void CreateLed(const std::string& name, int max_brightness, int brightness) {
    base::FilePath led(dir_.path().Append(name));
    base::CreateDirectory(led);

    std::string b_str = std::to_string(brightness);
    std::string mb_str = std::to_string(max_brightness);

    ASSERT_EQ(
        b_str.size(),
        base::WriteFile(led.Append("brightness"), b_str.c_str(), b_str.size()));
    ASSERT_EQ(mb_str.size(),
              base::WriteFile(
                  led.Append("max_brightness"), mb_str.c_str(), mb_str.size()));
  }

  void TearDown() { LedManager::ResetLedManager(); }

 private:
  base::ScopedTempDir dir_;
  std::string led_path_prefix_;
};

// Test that we can list the available LEDs.
TEST_F(LedTest, CanListLeds) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();
  ASSERT_NE(nullptr, client);

  int nleds = -1;
  char** leds = BPeripheralManagerClient_listLeds(client, &nleds);

  EXPECT_EQ(2, nleds);
  EXPECT_EQ("LED1", std::string(leds[0]));
  EXPECT_EQ("LED2", std::string(leds[1]));

  for (int i = 0; i < nleds; i++) {
    free(leds[i]);
  }
  free(leds);

  BPeripheralManagerClient_delete(client);
}

// Test that we can open an LED and act on it.
TEST_F(LedTest, CanOpenLed) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();
  ASSERT_NE(nullptr, client);

  BLed* led;

  ASSERT_EQ(0, BPeripheralManagerClient_openLed(client, "LED1", &led));

  uint32_t max_brightness = 0;
  EXPECT_EQ(0, BLed_getMaxBrightness(led, &max_brightness));
  EXPECT_EQ(255, max_brightness);

  uint32_t brightness = 0;
  EXPECT_EQ(0, BLed_setBrightness(led, 10));
  EXPECT_EQ(0, BLed_getBrightness(led, &brightness));
  EXPECT_EQ(10, brightness);

  BLed_delete(led);
  BPeripheralManagerClient_delete(client);
}

// Test that we can't open an unexisting LED.
TEST_F(LedTest, OpenningUnknownLed) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();
  ASSERT_NE(nullptr, client);

  BLed* led = nullptr;
  EXPECT_EQ(ENODEV, BPeripheralManagerClient_openLed(client, "hello", &led));
  EXPECT_EQ(nullptr, led);

  BPeripheralManagerClient_delete(client);
}

// Test that we can't open an LED twice.
TEST_F(LedTest, HandleConcurrentAccesses) {
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();
  ASSERT_NE(nullptr, client);

  // Can open LED1.
  BLed* led1;
  EXPECT_EQ(0, BPeripheralManagerClient_openLed(client, "LED1", &led1));

  // Fails to open it twice.
  BLed* led2;
  EXPECT_EQ(EBUSY, BPeripheralManagerClient_openLed(client, "LED1", &led2));

  // Can still open another LED.
  BLed* led3;
  EXPECT_EQ(0, BPeripheralManagerClient_openLed(client, "LED2", &led3));

  // Once the LED is released, we can take ownership of it.
  BLed_delete(led1);
  EXPECT_EQ(0, BPeripheralManagerClient_openLed(client, "LED1", &led2));

  BLed_delete(led2);
  BLed_delete(led3);
  BPeripheralManagerClient_delete(client);
}
