//
//  Copyright 2015 Google, Inc.
//
//  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.
//

#define LOG_TAG "bt_bluetooth_host"

#include "service/ipc/linux_ipc_host.h"

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>

#include <algorithm>

#include <base/base64.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>

#include "osi/include/log.h"
#include "osi/include/osi.h"
#include "service/adapter.h"

using bluetooth::Adapter;
using bluetooth::Uuid;

using namespace bluetooth::gatt;

namespace {

// IPC API is according to:
// https://docs.google.com/document/d/1eRnku-jAyVU1wGJsLT2CzWi0-8bs2g49s1b3FR_GApM
const char kSetAdapterNameCommand[] = "set-device-name";
const char kCreateServiceCommand[] = "create-service";
const char kDestroyServiceCommand[] = "destroy-service";
const char kAddCharacteristicCommand[] = "add-characteristic";
const char kSetCharacteristicValueCommand[] = "set-characteristic-value";
const char kSetAdvertisementCommand[] = "set-advertisement";
const char kSetScanResponseCommand[] = "set-scan-response";
const char kStartServiceCommand[] = "start-service";
const char kStopServiceCommand[] = "stop-service";
const char kWriteCharacteristicCommand[] = "write-characteristic";

// Useful values for indexing LinuxIPCHost::pfds_
// Not super general considering that we should be able to support
// many GATT FDs owned by one LinuxIPCHost.
enum {
  kFdIpc = 0,
  kFdGatt = 1,
  kPossibleFds = 2,
};

bool TokenBool(const std::string& text) { return text == "true"; }

}  // namespace

namespace ipc {

LinuxIPCHost::LinuxIPCHost(int sockfd, Adapter* adapter)
    : adapter_(adapter), pfds_(1, {sockfd, POLLIN, 0}) {}

LinuxIPCHost::~LinuxIPCHost() { close(pfds_[0].fd); }

bool LinuxIPCHost::EventLoop() {
  while (true) {
    int status =
        TEMP_FAILURE_RETRY(ppoll(pfds_.data(), pfds_.size(), nullptr, nullptr));
    if (status < 1) {
      LOG_ERROR(LOG_TAG, "ppoll error");
      return false;
    }

    if (pfds_[kFdIpc].revents && !OnMessage()) {
      return false;
    }

    if (pfds_.size() == kPossibleFds && pfds_[kFdGatt].revents &&
        !OnGattWrite()) {
      return false;
    }
  }
  return true;
}

bool LinuxIPCHost::OnSetAdapterName(const std::string& name) {
  std::string decoded_data;
  base::Base64Decode(name, &decoded_data);
  return adapter_->SetName(decoded_data);
}

bool LinuxIPCHost::OnCreateService(const std::string& service_uuid) {
  gatt_servers_[service_uuid] = std::unique_ptr<Server>(new Server);

  int gattfd;
  bool status = gatt_servers_[service_uuid]->Initialize(
      Uuid::FromString(service_uuid), &gattfd);
  if (!status) {
    LOG_ERROR(LOG_TAG, "Failed to initialize bluetooth");
    return false;
  }
  pfds_.resize(kPossibleFds);
  pfds_[kFdGatt] = {gattfd, POLLIN, 0};
  return true;
}

bool LinuxIPCHost::OnDestroyService(const std::string& service_uuid) {
  gatt_servers_.erase(service_uuid);
  close(pfds_[1].fd);
  pfds_.resize(1);
  return true;
}

bool LinuxIPCHost::OnAddCharacteristic(const std::string& service_uuid,
                                       const std::string& characteristic_uuid,
                                       const std::string& control_uuid,
                                       const std::string& options) {
  std::vector<std::string> option_tokens = base::SplitString(
      options, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);

  int properties_mask = 0;
  int permissions_mask = 0;

  if (std::find(option_tokens.begin(), option_tokens.end(), "notify") !=
      option_tokens.end()) {
    permissions_mask |= kPermissionRead;
    properties_mask |= kPropertyRead;
    properties_mask |= kPropertyNotify;
  }
  if (std::find(option_tokens.begin(), option_tokens.end(), "read") !=
      option_tokens.end()) {
    permissions_mask |= kPermissionRead;
    properties_mask |= kPropertyRead;
  }
  if (std::find(option_tokens.begin(), option_tokens.end(), "write") !=
      option_tokens.end()) {
    permissions_mask |= kPermissionWrite;
    properties_mask |= kPropertyWrite;
  }

  if (control_uuid.empty()) {
    gatt_servers_[service_uuid]->AddCharacteristic(
        Uuid::FromString(characteristic_uuid), properties_mask,
        permissions_mask);
  } else {
    gatt_servers_[service_uuid]->AddBlob(Uuid::FromString(characteristic_uuid),
                                         Uuid::FromString(control_uuid),
                                         properties_mask, permissions_mask);
  }
  return true;
}

bool LinuxIPCHost::OnSetCharacteristicValue(
    const std::string& service_uuid, const std::string& characteristic_uuid,
    const std::string& value) {
  std::string decoded_data;
  base::Base64Decode(value, &decoded_data);
  std::vector<uint8_t> blob_data(decoded_data.begin(), decoded_data.end());
  gatt_servers_[service_uuid]->SetCharacteristicValue(
      Uuid::FromString(characteristic_uuid), blob_data);
  return true;
}

bool LinuxIPCHost::OnSetAdvertisement(const std::string& service_uuid,
                                      const std::string& advertise_uuids,
                                      const std::string& advertise_data,
                                      const std::string& manufacturer_data,
                                      const std::string& transmit_name) {
  LOG_INFO(LOG_TAG, "%s: service:%s uuids:%s data:%s", __func__,
           service_uuid.c_str(), advertise_uuids.c_str(),
           advertise_data.c_str());

  std::vector<std::string> advertise_uuid_tokens = base::SplitString(
      advertise_uuids, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);

  // string -> vector<Uuid>
  std::vector<Uuid> ids;
  for (const auto& uuid_token : advertise_uuid_tokens)
    ids.emplace_back(Uuid::FromString(uuid_token));

  std::string decoded_data;
  base::Base64Decode(advertise_data, &decoded_data);
  std::vector<uint8_t> decoded_advertise_data(decoded_data.begin(),
                                              decoded_data.end());

  base::Base64Decode(manufacturer_data, &decoded_data);
  std::vector<uint8_t> decoded_manufacturer_data(decoded_data.begin(),
                                                 decoded_data.end());

  gatt_servers_[service_uuid]->SetAdvertisement(ids, decoded_advertise_data,
                                                decoded_manufacturer_data,
                                                TokenBool(transmit_name));
  return true;
}

bool LinuxIPCHost::OnSetScanResponse(const std::string& service_uuid,
                                     const std::string& scan_response_uuids,
                                     const std::string& scan_response_data,
                                     const std::string& manufacturer_data,
                                     const std::string& transmit_name) {
  std::vector<std::string> scan_response_uuid_tokens = base::SplitString(
      scan_response_uuids, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);

  // string -> vector<Uuid>
  std::vector<Uuid> ids;
  for (const auto& uuid_token : scan_response_uuid_tokens)
    ids.emplace_back(Uuid::FromString(uuid_token));

  std::string decoded_data;
  base::Base64Decode(scan_response_data, &decoded_data);
  std::vector<uint8_t> decoded_advertise_data(decoded_data.begin(),
                                              decoded_data.end());

  base::Base64Decode(manufacturer_data, &decoded_data);
  std::vector<uint8_t> decoded_manufacturer_data(decoded_data.begin(),
                                                 decoded_data.end());

  gatt_servers_[service_uuid]->SetScanResponse(ids, decoded_advertise_data,
                                               decoded_manufacturer_data,
                                               TokenBool(transmit_name));
  return true;
}

bool LinuxIPCHost::OnStartService(const std::string& service_uuid) {
  return gatt_servers_[service_uuid]->Start();
}

bool LinuxIPCHost::OnStopService(const std::string& service_uuid) {
  return gatt_servers_[service_uuid]->Stop();
}

bool LinuxIPCHost::OnMessage() {
  std::string ipc_msg;
  ssize_t size;

  OSI_NO_INTR(size =
                  recv(pfds_[kFdIpc].fd, &ipc_msg[0], 0, MSG_PEEK | MSG_TRUNC));
  if (-1 == size) {
    LOG_ERROR(LOG_TAG, "Error reading datagram size: %s", strerror(errno));
    return false;
  } else if (0 == size) {
    LOG_INFO(LOG_TAG, "%s:%d: Connection closed", __func__, __LINE__);
    return false;
  }

  ipc_msg.resize(size);
  OSI_NO_INTR(size = read(pfds_[kFdIpc].fd, &ipc_msg[0], ipc_msg.size()));
  if (-1 == size) {
    LOG_ERROR(LOG_TAG, "Error reading IPC: %s", strerror(errno));
    return false;
  } else if (0 == size) {
    LOG_INFO(LOG_TAG, "%s:%d: Connection closed", __func__, __LINE__);
    return false;
  }

  std::vector<std::string> tokens = base::SplitString(
      ipc_msg, "|", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  switch (tokens.size()) {
    case 2:
      if (tokens[0] == kSetAdapterNameCommand)
        return OnSetAdapterName(tokens[1]);
      if (tokens[0] == kCreateServiceCommand) return OnCreateService(tokens[1]);
      if (tokens[0] == kDestroyServiceCommand)
        return OnDestroyService(tokens[1]);
      if (tokens[0] == kStartServiceCommand) return OnStartService(tokens[1]);
      if (tokens[0] == kStopServiceCommand) return OnStopService(tokens[1]);
      break;
    case 4:
      if (tokens[0] == kSetCharacteristicValueCommand)
        return OnSetCharacteristicValue(tokens[1], tokens[2], tokens[3]);
      break;
    case 5:
      if (tokens[0] == kAddCharacteristicCommand)
        return OnAddCharacteristic(tokens[1], tokens[2], tokens[3], tokens[4]);
      break;
    case 6:
      if (tokens[0] == kSetAdvertisementCommand)
        return OnSetAdvertisement(tokens[1], tokens[2], tokens[3], tokens[4],
                                  tokens[5]);
      if (tokens[0] == kSetScanResponseCommand)
        return OnSetScanResponse(tokens[1], tokens[2], tokens[3], tokens[4],
                                 tokens[5]);
      break;
    default:
      break;
  }

  LOG_ERROR(LOG_TAG, "Malformed IPC message: %s", ipc_msg.c_str());
  return false;
}

bool LinuxIPCHost::OnGattWrite() {
  Uuid::UUID128Bit id;
  ssize_t r;

  OSI_NO_INTR(r = read(pfds_[kFdGatt].fd, id.data(), id.size()));
  if (r != id.size()) {
    LOG_ERROR(LOG_TAG, "Error reading GATT attribute ID");
    return false;
  }

  std::vector<uint8_t> value;
  // TODO(icoolidge): Generalize this for multiple clients.
  auto server = gatt_servers_.begin();
  server->second->GetCharacteristicValue(Uuid::From128BitBE(id), &value);
  const std::string value_string(value.begin(), value.end());
  std::string encoded_value;
  base::Base64Encode(value_string, &encoded_value);

  std::string transmit(kWriteCharacteristicCommand);
  transmit += "|" + server->first;
  transmit += "|" + base::HexEncode(id.data(), id.size());
  transmit += "|" + encoded_value;

  OSI_NO_INTR(r = write(pfds_[kFdIpc].fd, transmit.data(), transmit.size()));
  if (-1 == r) {
    LOG_ERROR(LOG_TAG, "Error replying to IPC: %s", strerror(errno));
    return false;
  }

  return true;
}

}  // namespace ipc
