// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdio.h>  // snprintf

#include "beacons.h"

namespace ble = fuchsia::bluetooth::le;

namespace bt_beacon_reader {

std::unique_ptr<IBeaconDetection> IBeaconDetection::Create(
    const ble::RemoteDevice& device) {
  if (!device.advertising_data ||
      device.advertising_data->manufacturer_specific_data->size() != 1) {
    return nullptr;
  }
  const std::vector<uint8_t>& data =
      *(*device.advertising_data->manufacturer_specific_data)[0].data;
  if (data[0] != 0x02) {
    return nullptr;
  }
  if (data[1] != data.size() - 2 || data.size() < 21) {
    return nullptr;
  }
  std::unique_ptr<IBeaconDetection> beacon(new IBeaconDetection);
  beacon->Read(data);
  return beacon;
}

void IBeaconDetection::Read(const std::vector<uint8_t>& data) {
  char temp[3];
  power_lvl_ = 0;
  uuid_.clear();
  for (int i = 2; i < 18; ++i) {
    snprintf(temp, 3, "%02x", data[i]);
    uuid_.append(temp, 2);
  }
  major_ = (data[18] << 8) + data[19];
  minor_ = (data[20] << 8) + data[21];
  // The power level field seems to be optional...
  if (data.size() > 22) {
    power_lvl_ = data[22];
  }
}

std::unique_ptr<TiltDetection> TiltDetection::Create(
    const ble::RemoteDevice& device) {
  std::unique_ptr<IBeaconDetection> beacon = IBeaconDetection::Create(device);
  if (!beacon) {
    return nullptr;
  }

  // All Tilt Hydrometers have uuids of the form:
  // a495bb-0c5b14b44b5121370f02d74de where the dash is 0-8,
  // corresponding to the 8 colors.
  if (beacon->uuid_.compare(0, 6, "a495bb") ||
      beacon->uuid_.compare(8, 24, "c5b14b44b5121370f02d74de")) {
    return nullptr;
  }
  // OK, it is a tilt!
  std::unique_ptr<TiltDetection> tilt(new TiltDetection);
  tilt->Read(beacon);
  tilt->identifier_ = *device.identifier;
  return tilt;
}

void TiltDetection::Print() {
  printf("Tilt %s: Temp: %dF, Gravity: %1.3f\n", color_string_.c_str(),
         temperature_F_, gravity_);
}

void TiltDetection::Read(const std::unique_ptr<IBeaconDetection>& beacon) {
  temperature_F_ = beacon->major_;
  color_ = beacon->uuid_[6] - '0';
  std::string colors[] = {"Invalid", "Red",  "Green",  "Black", "Purple",
                          "Orange",  "Blue", "Yellow", "Pink"};
  color_string_ = colors[color_ % 9];

  // negative gravities are just expressed as their value % 1000.
  // Since a specific gravity of beer at 1.5 is crazy, we'll draw the line
  // there.
  gravity_ = beacon->minor_ / 1000.0;
  if (beacon->minor_ < 500) {
    gravity_ += 1.0;
  }
}

}  // namespace bt_beacon_reader
