/*
 * 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 <unistd.h>

#include <memory>

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

#include <peripheralmanager/peripheral_manager_client.h>

void SetLed(const BSpiDevice* my_spi, uint8_t r, uint8_t g, uint8_t b) {
  uint8_t start_frame[] = {0x00, 0x00, 0x00, 0x00};
  uint8_t on_frame[4] = {0xff, 0x00, 0x00, 0x00};
  uint8_t end_frame[] = {0xff, 0xff, 0xff, 0xff};
  on_frame[1] = b;
  on_frame[2] = g;
  on_frame[3] = r;
  BSpiDevice_writeBuffer(my_spi, start_frame, sizeof(start_frame));
  BSpiDevice_writeBuffer(my_spi, on_frame, sizeof(on_frame));
  BSpiDevice_writeBuffer(my_spi, end_frame, sizeof(end_frame));
}

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

  LOG(INFO) << "PeripheralManager Client";

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

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

  // Open SPI bus.
  BSpiDevice* my_spi;
  int ret = BPeripheralManagerClient_openSpiDevice(client, "SPI2", &my_spi);
  if (ret) {
    LOG(ERROR) << "Failed to open Spi: " << strerror(ret);
    return 1;
  }

  BSpiDevice_setFrequency(my_spi, 400000);

  SetLed(my_spi, 0xff, 0x0, 0x0);
  sleep(1);
  SetLed(my_spi, 0x00, 0xff, 0x0);
  sleep(1);
  SetLed(my_spi, 0x00, 0x0, 0xff);
  sleep(1);

  BSpiDevice_delete(my_spi);

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

  LOG(INFO) << "Exiting";
  return 0;
}
