/*
 * 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 <arpa/inet.h>
#include <unistd.h>

#include <memory>

#include <base/logging.h>
#include <brillo/flag_helper.h>

#include <peripheralmanager/peripheral_manager_client.h>

int16_t swap_bytes(int16_t i) {
  return ((i & 0x00FF) << 8) + ((i & 0xFF00) >> 8);
}

int main(int argc, char* argv[]) {
  brillo::FlagHelper::Init(argc, argv, "PeripheralManager example.");
  logging::InitLogging(logging::LoggingSettings());

  // Get a client to the PeripheralManager.
  BPeripheralManagerClient* client = BPeripheralManagerClient_new();

  if (!client) {
    LOG(ERROR) << "Failed to connect to client";
    return 1;
  }

  // Open I2C device.
  BI2cDevice* i2c_device;
  int ret =
      BPeripheralManagerClient_openI2cDevice(client, "I2C6", 0x68, &i2c_device);
  if (ret) {
    LOG(ERROR) << "Failed to open I2C: " << strerror(ret);
    return 1;
  }

  // Turn the sensor on.
  ret = BI2cDevice_writeRegByte(i2c_device, 0x6B, 0);
  if (ret) {
    LOG(ERROR) << "Failed to setup the device: " << strerror(ret);
    return 1;
  }

  // Read the "who am I" register (contains the device address).
  uint8_t address;
  ret = BI2cDevice_readRegByte(i2c_device, 0x75, &address);
  if (ret) {
    LOG(ERROR) << "Failed to read the WHO AM I register: " << strerror(ret);
    return 1;
  }
  printf("I am at address is: 0x%X\n", address);

  int16_t temp = 0;
  ret = BI2cDevice_readRegWord(
      i2c_device, 0x41, reinterpret_cast<uint16_t*>(&temp));
  if (ret) {
    LOG(ERROR) << "Failed to read the temp: " << strerror(ret);
    return 1;
  }
  temp = ntohs(temp);
  float t = temp;
  printf("temp is: %.02f degrees Celsius.\n", t / 340 + 36.53);

  for (int j = 0; j < 50; j++) {

    // Read the values of the accelerometer.
    int16_t accel_data[3];

    uint32_t read;
    ret = BI2cDevice_readRegBuffer(i2c_device, 0x3B, &accel_data, 6, &read);
    if (ret || read != 6) {
      LOG(ERROR) << "Failed to read the buffer: " << strerror(ret);
      return 1;
    }

    printf("Accelerometer values: X=%i, Y=%i, Z=%i\n",
           swap_bytes(accel_data[0]),
           swap_bytes(accel_data[1]),
           swap_bytes(accel_data[2]));

    sleep(1);
  }

  BI2cDevice_delete(i2c_device);

  // Close the connection to PeripheralManager.
  BPeripheralManagerClient_delete(client);

  return 0;
}
