//
//  Copyright (C) 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.
//
#include "logging_helpers.h"

#include <string.h>

#include <string>

#define CASE_RETURN_TEXT(code) \
  case code:                   \
    return #code

const char* BtAvConnectionStateText(const btav_connection_state_t state) {
  switch (state) {
    CASE_RETURN_TEXT(BTAV_CONNECTION_STATE_DISCONNECTED);
    CASE_RETURN_TEXT(BTAV_CONNECTION_STATE_CONNECTING);
    CASE_RETURN_TEXT(BTAV_CONNECTION_STATE_CONNECTED);
    CASE_RETURN_TEXT(BTAV_CONNECTION_STATE_DISCONNECTING);
    default:
      return "Invalid AV connection state";
  }
}

const char* BtAvAudioStateText(const btav_audio_state_t state) {
  switch (state) {
    CASE_RETURN_TEXT(BTAV_AUDIO_STATE_REMOTE_SUSPEND);
    CASE_RETURN_TEXT(BTAV_AUDIO_STATE_STOPPED);
    CASE_RETURN_TEXT(BTAV_AUDIO_STATE_STARTED);
    default:
      return "Invalid audio state";
  }
}

const char* BtTransportText(const btgatt_transport_t t) {
  switch (t) {
    CASE_RETURN_TEXT(GATT_TRANSPORT_AUTO);
    CASE_RETURN_TEXT(GATT_TRANSPORT_BREDR);
    CASE_RETURN_TEXT(GATT_TRANSPORT_LE);
    default:
      return "unknown transport";
  }
}

const char* BtStateText(const bt_state_t state) {
  switch (state) {
    CASE_RETURN_TEXT(BT_STATE_OFF);
    CASE_RETURN_TEXT(BT_STATE_ON);
    default:
      return "unknown state code";
  }
}

const char* BtDiscoveryStateText(const bt_discovery_state_t state) {
  switch (state) {
    CASE_RETURN_TEXT(BT_DISCOVERY_STOPPED);
    CASE_RETURN_TEXT(BT_DISCOVERY_STARTED);
    default:
      return "unknown discovery state code";
  }
}

const char* BtScanModeText(const bt_scan_mode_t mode) {
  switch (mode) {
    CASE_RETURN_TEXT(BT_SCAN_MODE_NONE);
    CASE_RETURN_TEXT(BT_SCAN_MODE_CONNECTABLE);
    CASE_RETURN_TEXT(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
    default:
      return "unknown scan mode";
  }
}

const char* BtStatusText(const bt_status_t status) {
  switch (status) {
    CASE_RETURN_TEXT(BT_STATUS_SUCCESS);
    CASE_RETURN_TEXT(BT_STATUS_FAIL);
    CASE_RETURN_TEXT(BT_STATUS_NOT_READY);
    CASE_RETURN_TEXT(BT_STATUS_NOMEM);
    CASE_RETURN_TEXT(BT_STATUS_DONE);
    CASE_RETURN_TEXT(BT_STATUS_BUSY);
    CASE_RETURN_TEXT(BT_STATUS_UNSUPPORTED);
    CASE_RETURN_TEXT(BT_STATUS_PARM_INVALID);
    CASE_RETURN_TEXT(BT_STATUS_UNHANDLED);
    CASE_RETURN_TEXT(BT_STATUS_AUTH_FAILURE);
    CASE_RETURN_TEXT(BT_STATUS_RMT_DEV_DOWN);
    CASE_RETURN_TEXT(BT_STATUS_AUTH_REJECTED);
    default:
      return "unknown status code";
  }
}

const char* BtPropertyText(const bt_property_type_t prop) {
  switch (prop) {
    CASE_RETURN_TEXT(BT_PROPERTY_BDNAME);
    CASE_RETURN_TEXT(BT_PROPERTY_BDADDR);
    CASE_RETURN_TEXT(BT_PROPERTY_UUIDS);
    CASE_RETURN_TEXT(BT_PROPERTY_CLASS_OF_DEVICE);
    CASE_RETURN_TEXT(BT_PROPERTY_TYPE_OF_DEVICE);
    CASE_RETURN_TEXT(BT_PROPERTY_SERVICE_RECORD);
    CASE_RETURN_TEXT(BT_PROPERTY_ADAPTER_SCAN_MODE);
    CASE_RETURN_TEXT(BT_PROPERTY_ADAPTER_BONDED_DEVICES);
    CASE_RETURN_TEXT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT);
    CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_FRIENDLY_NAME);
    CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_RSSI);
    CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_VERSION_INFO);
    CASE_RETURN_TEXT(BT_PROPERTY_LOCAL_LE_FEATURES);
    CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP);
    default:
      return "Invalid property";
  }
}

const char* BtEventText(const bt_cb_thread_evt evt) {
  switch (evt) {
    CASE_RETURN_TEXT(ASSOCIATE_JVM);
    CASE_RETURN_TEXT(DISASSOCIATE_JVM);
    default:
      return "unknown state code";
  }
}

const char* BtAclText(const bt_acl_state_t code) {
  switch (code) {
    CASE_RETURN_TEXT(BT_ACL_STATE_CONNECTED);
    CASE_RETURN_TEXT(BT_ACL_STATE_DISCONNECTED);
    default:
      return "unknown ACL code";
  }
}

std::string BtAddrString(const RawAddress* addr) {
  char buffer[20];
  snprintf(buffer, sizeof(buffer), "%02X:%02X:%02X:%02X:%02X:%02X",
           addr->address[0], addr->address[1], addr->address[2],
           addr->address[3], addr->address[4], addr->address[5]);
  return std::string(buffer);
}
