/*
 * Copyright (C) 2015 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 "peripheral_manager.h"

#include <base/logging.h>
#include <binderwrapper/binder_wrapper.h>
#include <binderwrapper/stub_binder_wrapper.h>
#include <hardware/hardware.h>
#include <hardware/peripheral_io.h>

#include "gpio_driver_sysfs.h"
#include "gpio_manager.h"
#include "i2c_driver_i2cdev.h"
#include "i2c_manager.h"
#include "led_driver_sysfs.h"
#include "led_manager.h"
#include "pin_mux_manager.h"
#include "spi_driver_spidev.h"
#include "uart_driver_sysfs.h"
#include "uart_manager.h"

namespace android {
namespace {

// Gpio callbacks
static int RegisterGpioSysfs(const char* name, uint32_t index) {
  return GpioManager::GetGpioManager()->RegisterGpioSysfs(name, index);
}

static int SetGpioPinMux(const char* name, const char* source) {
  return GpioManager::GetGpioManager()->SetPinMux(name, source);
}

// Spi callbacks
static int RegisterSpiDevBus(const char* name, uint32_t bus, uint32_t cs) {
  return SpiManager::GetSpiManager()->RegisterSpiDevBus(name, bus, cs);
}

static int SetSpiPinMux(const char* name, const char* source) {
  return SpiManager::GetSpiManager()->SetPinMux(name, source);
}

// Led callbacks
static int RegisterLedSysfs(const char* name, const char* sysfs_name) {
  return LedManager::GetLedManager()->RegisterLedSysfs(name, sysfs_name);
}

// Uart callbacks
static int RegisterUartBus(const char* name, const char* dev_name) {
  return UartManager::GetManager()->RegisterUartDevice(name, dev_name);
}

static int SetUartPinMux(const char* name, const char* source) {
  return UartManager::GetManager()->SetPinMux(name, source);
}

// I2c callbacks
static int RegisterI2cDevBus(const char* name, uint32_t bus) {
  return I2cManager::GetI2cManager()->RegisterI2cDevBus(name, bus);
}

static int SetI2cPinMux(const char* name, const char* source) {
  return I2cManager::GetI2cManager()->SetPinMux(name, source);
}

// Pin Mux callbacks.
static int RegisterPin(const char* name,
                       int gpio,
                       pin_mux_callbacks callbacks) {
  return PinMuxManager::GetPinMuxManager()->RegisterPin(name, gpio, callbacks);
}

static int RegisterPinGroup(const char* name, char** pins, size_t nr_pins) {
  std::set<std::string> pins_set;
  for (size_t i = 0; i < nr_pins; i++)
    pins_set.emplace(pins[i]);
  return PinMuxManager::GetPinMuxManager()->RegisterPinGroup(name, pins_set);
}

static int RegisterSource(const char* name, char** groups, size_t nr_groups) {
  std::set<std::string> groups_set;
  for (size_t i = 0; i < nr_groups; i++)
    groups_set.emplace(groups[i]);
  return PinMuxManager::GetPinMuxManager()->RegisterSource(name, groups_set);
}

static int RegisterSimpleSource(const char* name,
                                const char** pins,
                                size_t nr_pins) {
  std::set<std::string> pins_set;
  for (size_t i = 0; i < nr_pins; i++)
    pins_set.emplace(pins[i]);
  return PinMuxManager::GetPinMuxManager()->RegisterSimpleSource(name,
                                                                 pins_set);
}

}  // namespace

PeripheralManager::PeripheralManager() {}

PeripheralManager::~PeripheralManager() = default;

bool PeripheralManager::Init() {
  if (!RegisterDrivers())
    return false;

  if (!InitHal())
    return false;

  String8 interface_desc(getInterfaceDescriptor());
  return BinderWrapper::Get()->RegisterService(interface_desc.string(), this);
}

Status PeripheralManager::GetClient(const sp<IBinder>& lifeline,
                                    sp<os::IPeripheralManagerClient>* client) {
  sp<PeripheralManagerClient> c = new PeripheralManagerClient;
  *client = c;

  lifeline->linkToDeath(this);
  mapping_.emplace(lifeline.get(), c);
  VLOG(1) << "client connecting " << mapping_.size();

  return Status::ok();
}

void PeripheralManager::binderDied(const wp<IBinder>& who) {
  mapping_.erase(who.unsafe_get());
  VLOG(1) << "client disconnecting " << mapping_.size();
}

bool PeripheralManager::RegisterDrivers() {
  if (!SpiManager::GetSpiManager()->RegisterDriver(
          std::unique_ptr<SpiDriverInfoBase>(
              new SpiDriverInfo<SpiDriverSpiDev, CharDeviceFactory*>(
                  nullptr)))) {
    LOG(ERROR) << "Failed to load driver: SpiDriverSpiDev";
    return false;
  }
  if (!I2cManager::GetI2cManager()->RegisterDriver(
          std::unique_ptr<I2cDriverInfoBase>(
              new I2cDriverInfo<I2cDriverI2cDev, CharDeviceFactory*>(
                  nullptr)))) {
    LOG(ERROR) << "Failed to load driver: I2cDriverI2cDev";
    return false;
  }
  if (!GpioManager::GetGpioManager()->RegisterDriver(
          std::unique_ptr<GpioDriverInfoBase>(
              new GpioDriverInfo<GpioDriverSysfs, void*>(nullptr)))) {
    LOG(ERROR) << "Failed to load driver: GpioDriverSysfs";
    return false;
  }
  if (!LedManager::GetLedManager()->RegisterDriver(
          std::unique_ptr<LedDriverInfoBase>(
              new LedDriverInfo<LedDriverSysfs, std::string*>(nullptr)))) {
    LOG(ERROR) << "Failed to load driver: LedDriverSysfs";
    return false;
  }
  if (!UartManager::GetManager()->RegisterDriver(
          std::unique_ptr<UartDriverInfoBase>(
              new UartDriverInfo<UartDriverSysfs, CharDeviceFactory*>(
                  nullptr)))) {
    LOG(ERROR) << "Failed to load driver: UartDriverSysfs";
    return false;
  }
  return true;
}

bool PeripheralManager::InitHal() {
  const hw_module_t* module = nullptr;
  if (hw_get_module(PERIPHERAL_IO_HARDWARE_MODULE_ID, &module) != 0) {
    LOG(ERROR) << "Failed to load HAL" << module;
    return true;
  }

  const peripheral_io_module_t* peripheral_module =
      reinterpret_cast<const peripheral_io_module_t*>(module);

  struct peripheral_registration_cb_t callbacks = {
      // Gpio
      .register_gpio_sysfs = RegisterGpioSysfs,
      .set_gpio_pin_mux = SetGpioPinMux,

      // Spi
      .register_spi_dev_bus = RegisterSpiDevBus,
      .set_spi_pin_mux = SetSpiPinMux,

      // Led
      .register_led_sysfs = RegisterLedSysfs,

      // Uart
      .register_uart_bus = RegisterUartBus,
      .set_uart_pin_mux = SetUartPinMux,

      // I2c
      .register_i2c_dev_bus = RegisterI2cDevBus,
      .set_i2c_pin_mux = SetI2cPinMux,

      // Pin Mux
      .register_pin = RegisterPin,
      .register_pin_group = RegisterPinGroup,
      .register_source = RegisterSource,
      .register_simple_source = RegisterSimpleSource,
  };

  peripheral_module->register_devices(peripheral_module, &callbacks);

  return true;
}

}  // namespace android
