/*
 * Copyright (C) 2020 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 "chpp/app.h"

#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include "chpp/clients.h"
#include "chpp/clients/discovery.h"
#ifdef CHPP_CLIENT_ENABLED_LOOPBACK
#include "chpp/clients/loopback.h"
#endif
#include "chpp/log.h"
#include "chpp/macros.h"
#include "chpp/notifier.h"
#include "chpp/pal_api.h"
#include "chpp/services.h"
#include "chpp/services/discovery.h"
#include "chpp/services/loopback.h"
#include "chpp/services/nonhandle.h"

/************************************************
 *  Prototypes
 ***********************************************/

static bool chppProcessPredefinedClientRequest(struct ChppAppState *context,
                                               uint8_t *buf, size_t len);
static bool chppProcessPredefinedServiceResponse(struct ChppAppState *context,
                                                 uint8_t *buf, size_t len);
static bool chppProcessPredefinedClientNotification(
    struct ChppAppState *context, uint8_t *buf, size_t len);
static bool chppProcessPredefinedServiceNotification(
    struct ChppAppState *context, uint8_t *buf, size_t len);

static bool chppDatagramLenIsOk(struct ChppAppState *context,
                                struct ChppAppHeader *rxHeader, size_t len);
ChppDispatchFunction *chppGetDispatchFunction(struct ChppAppState *context,
                                              uint8_t handle,
                                              enum ChppMessageType type);
static inline const struct ChppService *chppServiceOfHandle(
    struct ChppAppState *appContext, uint8_t handle);
static inline const struct ChppClient *chppClientOfHandle(
    struct ChppAppState *appContext, uint8_t handle);
static inline void *chppServiceContextOfHandle(struct ChppAppState *appContext,
                                               uint8_t handle);
static inline void *chppClientContextOfHandle(struct ChppAppState *appContext,
                                              uint8_t handle);
static void *chppClientServiceContextOfHandle(struct ChppAppState *appContext,
                                              uint8_t handle,
                                              enum ChppMessageType type);

static void chppProcessPredefinedHandleDatagram(struct ChppAppState *context,
                                                uint8_t *buf, size_t len);
static void chppProcessNegotiatedHandleDatagram(struct ChppAppState *context,
                                                uint8_t *buf, size_t len);

/************************************************
 *  Private Functions
 ***********************************************/

/**
 * Processes a client request that is determined to be for a predefined CHPP
 * service.
 *
 * @param context Maintains status for each app layer instance.
 * @param buf Input data. Cannot be null.
 * @param len Length of input data in bytes.
 *
 * @return False if handle is invalid. True otherwise.
 */
static bool chppProcessPredefinedClientRequest(struct ChppAppState *context,
                                               uint8_t *buf, size_t len) {
  struct ChppAppHeader *rxHeader = (struct ChppAppHeader *)buf;
  bool handleValid = true;
  bool dispatchResult = true;

  switch (rxHeader->handle) {
    case CHPP_HANDLE_LOOPBACK: {
      dispatchResult = chppDispatchLoopbackClientRequest(context, buf, len);
      break;
    }

    case CHPP_HANDLE_DISCOVERY: {
      dispatchResult = chppDispatchDiscoveryClientRequest(context, buf, len);
      break;
    }

    default: {
      handleValid = false;
    }
  }

  if (dispatchResult == false) {
    CHPP_LOGE("Handle=%" PRIu8
              " received unknown client request. command=%#x, transaction ID="
              "%" PRIu8,
              rxHeader->handle, rxHeader->command, rxHeader->transaction);
  }

  return handleValid;
}

/**
 * Processes a service response that is determined to be for a predefined CHPP
 * client.
 *
 * @param context Maintains status for each app layer instance.
 * @param buf Input data. Cannot be null.
 * @param len Length of input data in bytes.
 *
 * @return False if handle is invalid. True otherwise.
 */
static bool chppProcessPredefinedServiceResponse(struct ChppAppState *context,
                                                 uint8_t *buf, size_t len) {
  struct ChppAppHeader *rxHeader = (struct ChppAppHeader *)buf;
  bool handleValid = true;
  bool dispatchResult = true;

  switch (rxHeader->handle) {
#ifdef CHPP_CLIENT_ENABLED_LOOPBACK
    case CHPP_HANDLE_LOOPBACK: {
      dispatchResult = chppDispatchLoopbackServiceResponse(context, buf, len);
      break;
    }
#endif  // CHPP_CLIENT_ENABLED_LOOPBACK

#ifdef CHPP_CLIENT_ENABLED_DISCOVERY
    case CHPP_HANDLE_DISCOVERY: {
      dispatchResult = chppDispatchDiscoveryServiceResponse(context, buf, len);
      break;
    }
#endif  // CHPP_CLIENT_ENABLED_DISCOVERY

    default: {
      handleValid = false;
    }
  }

  if (dispatchResult == false) {
    CHPP_LOGE("Handle=%" PRIu8
              " received unknown server response. command=%#x, transaction ID="
              "%" PRIu8,
              rxHeader->handle, rxHeader->command, rxHeader->transaction);
  }

  return handleValid;
}

/**
 * Processes a client notification that is determined to be for a predefined
 * CHPP service.
 *
 * @param context Maintains status for each app layer instance.
 * @param buf Input data. Cannot be null.
 * @param len Length of input data in bytes.
 *
 * @return False if handle is invalid. True otherwise.
 */
static bool chppProcessPredefinedClientNotification(
    struct ChppAppState *context, uint8_t *buf, size_t len) {
  struct ChppAppHeader *rxHeader = (struct ChppAppHeader *)buf;
  bool handleValid = true;
  bool dispatchResult = true;

  // No predefined services support these yet
  handleValid = false;

  UNUSED_VAR(context);
  UNUSED_VAR(len);
  UNUSED_VAR(rxHeader);
  UNUSED_VAR(dispatchResult);

  return handleValid;
}

/**
 * Processes a service notification that is determined to be for a predefined
 * CHPP client.
 *
 * @param context Maintains status for each app layer instance.
 * @param buf Input data. Cannot be null.
 * @param len Length of input data in bytes.
 *
 * @return False if handle is invalid. True otherwise.
 */
static bool chppProcessPredefinedServiceNotification(
    struct ChppAppState *context, uint8_t *buf, size_t len) {
  struct ChppAppHeader *rxHeader = (struct ChppAppHeader *)buf;
  bool handleValid = true;
  bool dispatchResult = true;

  // No predefined clients support these yet
  handleValid = false;

  UNUSED_VAR(context);
  UNUSED_VAR(len);
  UNUSED_VAR(rxHeader);
  UNUSED_VAR(dispatchResult);

  return handleValid;
}

/**
 * Verifies if the length of a Rx Datagram from the transport layer is
 * sufficient for the associated service.
 *
 * @param context Maintains status for each app layer instance.
 * @param rxHeader The pointer to the datagram RX header.
 * @param len Length of the datagram in bytes.
 *
 * @return true if length is ok.
 */
static bool chppDatagramLenIsOk(struct ChppAppState *context,
                                struct ChppAppHeader *rxHeader, size_t len) {
  size_t minLen = SIZE_MAX;
  uint8_t handle = rxHeader->handle;

  if (handle < CHPP_HANDLE_NEGOTIATED_RANGE_START) {  // Predefined
    switch (handle) {
      case CHPP_HANDLE_NONE:
        minLen = sizeof_member(struct ChppAppHeader, handle);
        break;

      case CHPP_HANDLE_LOOPBACK:
        minLen = sizeof_member(struct ChppAppHeader, handle) +
                 sizeof_member(struct ChppAppHeader, type);
        break;

      case CHPP_HANDLE_DISCOVERY:
        minLen = sizeof(struct ChppAppHeader);
        break;

      default:
        CHPP_LOGE("Invalid predefined handle %" PRIu8, handle);
    }

  } else {  // Negotiated
    enum ChppMessageType messageType =
        CHPP_APP_GET_MESSAGE_TYPE(rxHeader->type);
    switch (messageType) {
      case CHPP_MESSAGE_TYPE_CLIENT_REQUEST:
      case CHPP_MESSAGE_TYPE_CLIENT_NOTIFICATION: {
        minLen = chppServiceOfHandle(context, handle)->minLength;
        break;
      }
      case CHPP_MESSAGE_TYPE_SERVICE_RESPONSE:
      case CHPP_MESSAGE_TYPE_SERVICE_NOTIFICATION: {
        minLen = chppClientOfHandle(context, handle)->minLength;
        break;
      }
      default: {
        CHPP_LOGE("Invalid message type %d", messageType);
        break;
      }
    }
  }

  if (len < minLen) {
    CHPP_LOGE("Received datagram too short for handle=%" PRIu8
              ", len=%" PRIuSIZE " < %" PRIuSIZE,
              handle, len, minLen);
  }
  return (len >= minLen);
}

/**
 * Returns the dispatch function of a particular negotiated client/service
 * handle and message type. This shall be null if it is unsupported by the
 * service.
 *
 * @param context Maintains status for each app layer instance.
 * @param handle Handle number for the client/service.
 * @param type Message type.
 *
 * @return Pointer to a function that dispatches incoming datagrams for any
 * particular client/service.
 */
ChppDispatchFunction *chppGetDispatchFunction(struct ChppAppState *context,
                                              uint8_t handle,
                                              enum ChppMessageType type) {
  switch (CHPP_APP_GET_MESSAGE_TYPE(type)) {
    case CHPP_MESSAGE_TYPE_CLIENT_REQUEST: {
      return chppServiceOfHandle(context, handle)->requestDispatchFunctionPtr;
      break;
    }
    case CHPP_MESSAGE_TYPE_SERVICE_RESPONSE: {
      return chppClientOfHandle(context, handle)->responseDispatchFunctionPtr;
      break;
    }
    case CHPP_MESSAGE_TYPE_CLIENT_NOTIFICATION: {
      return chppServiceOfHandle(context, handle)
          ->notificationDispatchFunctionPtr;
      break;
    }
    case CHPP_MESSAGE_TYPE_SERVICE_NOTIFICATION: {
      return chppClientOfHandle(context, handle)
          ->notificationDispatchFunctionPtr;
      break;
    }
    default: {
      return NULL;
    }
  }
}

/**
 * Returns a pointer to the ChppService struct of a particular negotiated
 * service handle.
 *
 * @param context Maintains status for each app layer instance.
 * @param handle Handle number for the service.
 *
 * @return Pointer to the ChppService struct of a particular service handle.
 */
static inline const struct ChppService *chppServiceOfHandle(
    struct ChppAppState *context, uint8_t handle) {
  CHPP_DEBUG_ASSERT(CHPP_SERVICE_INDEX_OF_HANDLE(handle) <
                    context->registeredServiceCount);
  return context->registeredServices[CHPP_SERVICE_INDEX_OF_HANDLE(handle)];
}

/**
 * Returns a pointer to the ChppClient struct of a particular negotiated
 * handle. Returns null if a client doesn't exist for the handle.
 *
 * @param context Maintains status for each app layer instance.
 * @param handle Handle number for the service.
 *
 * @return Pointer to the ChppClient struct matched to a particular handle.
 */
static inline const struct ChppClient *chppClientOfHandle(
    struct ChppAppState *context, uint8_t handle) {
  CHPP_DEBUG_ASSERT(CHPP_SERVICE_INDEX_OF_HANDLE(handle) <
                    context->registeredClientCount);
  return context->registeredClients[context->clientIndexOfServiceIndex
                                        [CHPP_SERVICE_INDEX_OF_HANDLE(handle)]];
}

/**
 * Returns a pointer to the service struct of a particular negotiated service
 * handle.
 *
 * @param context Maintains status for each app layer instance.
 * @param handle Handle number for the service.
 *
 * @return Pointer to the context struct of the service.
 */
static inline void *chppServiceContextOfHandle(struct ChppAppState *context,
                                               uint8_t handle) {
  CHPP_DEBUG_ASSERT(CHPP_SERVICE_INDEX_OF_HANDLE(handle) <
                    context->registeredServiceCount);
  return context
      ->registeredServiceContexts[CHPP_SERVICE_INDEX_OF_HANDLE(handle)];
}

/**
 * Returns a pointer to the client struct of a particular negotiated client
 * handle.
 *
 * @param context Maintains status for each app layer instance.
 * @param handle Handle number for the service.
 *
 * @return Pointer to the ChppService struct of the client.
 */
static inline void *chppClientContextOfHandle(struct ChppAppState *context,
                                              uint8_t handle) {
  CHPP_DEBUG_ASSERT(CHPP_SERVICE_INDEX_OF_HANDLE(handle) <
                    context->registeredClientCount);
  return context
      ->registeredClientContexts[context->clientIndexOfServiceIndex
                                     [CHPP_SERVICE_INDEX_OF_HANDLE(handle)]];
}

/**
 * Returns a pointer to the client/service struct of a particular negotiated
 * client/service handle.
 *
 * @param appContext Maintains status for each app layer instance.
 * @param handle Handle number for the service.
 * @param type Message type (indicates if this is for a client or service).
 *
 * @return Pointer to the client/service struct of the service handle.
 */
static void *chppClientServiceContextOfHandle(struct ChppAppState *appContext,
                                              uint8_t handle,
                                              enum ChppMessageType type) {
  switch (CHPP_APP_GET_MESSAGE_TYPE(type)) {
    case CHPP_MESSAGE_TYPE_CLIENT_REQUEST:
    case CHPP_MESSAGE_TYPE_CLIENT_NOTIFICATION: {
      return chppServiceContextOfHandle(appContext, handle);
      break;
    }
    case CHPP_MESSAGE_TYPE_SERVICE_RESPONSE:
    case CHPP_MESSAGE_TYPE_SERVICE_NOTIFICATION: {
      return chppClientContextOfHandle(appContext, handle);
      break;
    }
    default: {
      CHPP_LOGE("Cannot provide context for unknown message type=0x%" PRIx8
                " (handle=%" PRIu8 ")",
                type, handle);
      return NULL;
    }
  }
}

/**
 * Processes a received datagram that is determined to be for a predefined CHPP
 * service. Responds with an error if unsuccessful.
 *
 * @param context Maintains status for each app layer instance.
 * @param buf Input data. Cannot be null.
 * @param len Length of input data in bytes.
 */
static void chppProcessPredefinedHandleDatagram(struct ChppAppState *context,
                                                uint8_t *buf, size_t len) {
  struct ChppAppHeader *rxHeader = (struct ChppAppHeader *)buf;
  bool success = true;

  switch (CHPP_APP_GET_MESSAGE_TYPE(rxHeader->type)) {
    case CHPP_MESSAGE_TYPE_CLIENT_REQUEST: {
      success = chppProcessPredefinedClientRequest(context, buf, len);
      break;
    }
    case CHPP_MESSAGE_TYPE_CLIENT_NOTIFICATION: {
      success = chppProcessPredefinedClientNotification(context, buf, len);
      break;
    }
    case CHPP_MESSAGE_TYPE_SERVICE_RESPONSE: {
      success = chppProcessPredefinedServiceResponse(context, buf, len);
      break;
    }
    case CHPP_MESSAGE_TYPE_SERVICE_NOTIFICATION: {
      success = chppProcessPredefinedServiceNotification(context, buf, len);
      break;
    }
    default: {
      success = false;
    }
  }

  if (success == false) {
    CHPP_LOGE("Predefined handle=%" PRIu8
              " does not support message type=0x%" PRIx8 " (len=%" PRIuSIZE
              ", transaction ID=%" PRIu8 ")",
              rxHeader->handle, rxHeader->type, len, rxHeader->transaction);
    chppEnqueueTxErrorDatagram(context->transportContext,
                               CHPP_TRANSPORT_ERROR_APPLAYER);
  }
}

/**
 * Processes a received datagram that is determined to be for a negotiated CHPP
 * service. Responds with an error if unsuccessful.
 *
 * @param context Maintains status for each app layer instance.
 * @param buf Input data. Cannot be null.
 * @param len Length of input data in bytes.
 */
static void chppProcessNegotiatedHandleDatagram(struct ChppAppState *context,
                                                uint8_t *buf, size_t len) {
  struct ChppAppHeader *rxHeader = (struct ChppAppHeader *)buf;
  enum ChppMessageType messageType = CHPP_APP_GET_MESSAGE_TYPE(rxHeader->type);

  void *clientServiceContext =
      chppClientServiceContextOfHandle(context, rxHeader->handle, messageType);
  if (clientServiceContext == NULL) {
    CHPP_LOGE("Negotiated handle=%" PRIu8 " for RX message type=0x%" PRIx8
              " is missing context (len=%" PRIuSIZE ", transaction ID=%" PRIu8
              ")",
              rxHeader->handle, rxHeader->type, len, rxHeader->transaction);
    chppEnqueueTxErrorDatagram(context->transportContext,
                               CHPP_TRANSPORT_ERROR_APPLAYER);
    CHPP_DEBUG_ASSERT(false);

  } else {
    ChppDispatchFunction *dispatchFunc =
        chppGetDispatchFunction(context, rxHeader->handle, messageType);
    if (dispatchFunc == NULL) {
      CHPP_LOGE("Negotiated handle=%" PRIu8
                " does not support RX message type=0x%" PRIx8 " (len=%" PRIuSIZE
                ", transaction ID=%" PRIu8 ")",
                rxHeader->handle, rxHeader->type, len, rxHeader->transaction);
      chppEnqueueTxErrorDatagram(context->transportContext,
                                 CHPP_TRANSPORT_ERROR_APPLAYER);

    } else {
      // All good. Dispatch datagram and possibly notify a waiting client

      enum ChppAppErrorCode error =
          dispatchFunc(clientServiceContext, buf, len);
      if (error != CHPP_APP_ERROR_NONE) {
        CHPP_LOGE("Dispatching RX datagram failed. error=0x%" PRIx16
                  " handle=0x%" PRIx8 ", type =0x%" PRIx8
                  ", transaction ID=%" PRIu8 ", command=0x%" PRIx16
                  ", len=%" PRIuSIZE,
                  error, rxHeader->handle, rxHeader->type,
                  rxHeader->transaction, rxHeader->command, len);

        // Only client requests require a dispatch failure response.
        if (messageType == CHPP_MESSAGE_TYPE_CLIENT_REQUEST) {
          struct ChppAppHeader *response =
              chppAllocServiceResponseFixed(rxHeader, struct ChppAppHeader);
          if (response == NULL) {
            CHPP_LOG_OOM();
          } else {
            response->error = CHPP_ATTR_AND_ERROR_TO_PACKET_CODE(
                CHPP_TRANSPORT_ATTR_NONE, error);
            chppEnqueueTxDatagramOrFail(context->transportContext, response,
                                        sizeof(*response));
          }
        }
      } else if (messageType == CHPP_MESSAGE_TYPE_SERVICE_RESPONSE) {
        // Datagram is a service response. Check for synchronous operation and
        // notify waiting client if needed.

        struct ChppClientState *clientContext =
            (struct ChppClientState *)clientServiceContext;
        chppMutexLock(&clientContext->responseMutex);
        clientContext->responseReady = true;
        CHPP_LOGD(
            "Finished dispatching a service response. Notifying a potential "
            "synchronous client");
        chppConditionVariableSignal(&clientContext->responseCondVar);
        chppMutexUnlock(&clientContext->responseMutex);
      }
    }
  }
}

/************************************************
 *  Public Functions
 ***********************************************/

void chppAppInit(struct ChppAppState *appContext,
                 struct ChppTransportState *transportContext) {
  // Default initialize all service/clients
  struct ChppClientServiceSet set;
  memset(&set, 0xff, sizeof(set));  // set all bits to 1

  chppAppInitWithClientServiceSet(appContext, transportContext, set);
}

void chppAppInitWithClientServiceSet(
    struct ChppAppState *appContext,
    struct ChppTransportState *transportContext,
    struct ChppClientServiceSet clientServiceSet) {
  CHPP_NOT_NULL(appContext);
  CHPP_NOT_NULL(transportContext);

  CHPP_LOGI("Initializing the CHPP app layer");

  // Don't reset entire ChppAppState to avoid clearing non-transient
  // contents e.g. discovery mutex/condvar/states.
  appContext->registeredServiceCount = 0;
  memset(appContext->registeredServices, 0,
         sizeof(appContext->registeredServices));
  memset(appContext->registeredServiceContexts, 0,
         sizeof(appContext->registeredServiceContexts));
  appContext->registeredClientCount = 0;
  memset(appContext->registeredClients, 0,
         sizeof(appContext->registeredClients));
  memset(appContext->registeredClientContexts, 0,
         sizeof(appContext->registeredClientContexts));
  memset(appContext->clientIndexOfServiceIndex, 0,
         sizeof(appContext->clientIndexOfServiceIndex));

  appContext->clientServiceSet = clientServiceSet;
  appContext->transportContext = transportContext;

#ifdef CHPP_CLIENT_ENABLED_DISCOVERY
  chppDiscoveryInit(appContext);
#endif  // CHPP_CLIENT_ENABLED_DISCOVERY
  chppPalSystemApiInit(appContext);
#ifdef CHPP_SERVICE_ENABLED
  chppRegisterCommonServices(appContext);
#endif
#ifdef CHPP_CLIENT_ENABLED
  chppRegisterCommonClients(appContext);
#endif
}

void chppAppDeinit(struct ChppAppState *appContext) {
  chppAppDeinitTransient(appContext);

#ifdef CHPP_CLIENT_ENABLED_DISCOVERY
  // Discovery should only be deinitialized on true CHPP app deinit
  // (shutdown), since a client may be waiting on discovery completion
  // during a transient deinit (reset).
  chppDiscoveryDeinit(appContext);
#endif  // CHPP_CLIENT_ENABLED_DISCOVERY
}

void chppAppDeinitTransient(struct ChppAppState *appContext) {
  CHPP_NOT_NULL(appContext);

  CHPP_LOGI("Deinitializing the CHPP app layer");

#ifdef CHPP_CLIENT_ENABLED
  chppDeregisterCommonClients(appContext);
#endif
#ifdef CHPP_SERVICE_ENABLED
  chppDeregisterCommonServices(appContext);
#endif
  chppPalSystemApiDeinit(appContext);
}

void chppProcessRxDatagram(struct ChppAppState *context, uint8_t *buf,
                           size_t len) {
  struct ChppAppHeader *rxHeader = (struct ChppAppHeader *)buf;

  if (len == 0) {
    CHPP_LOGE("chppProcessRxDatagram called with payload length of 0");
    CHPP_DEBUG_ASSERT(false);

  } else if (len < sizeof(struct ChppAppHeader)) {
    uint8_t *handle = (uint8_t *)buf;
    CHPP_LOGD("App layer RX datagram (len=%" PRIuSIZE ") for handle=%" PRIu8,
              len, *handle);

  } else {
    CHPP_LOGD("App layer RX datagram (len=%" PRIuSIZE ") for handle=%" PRIu8
              ", type=0x%" PRIx8 ", transaction ID=%" PRIu8 ", error=%" PRIu8
              ", command=0x%" PRIx16,
              len, rxHeader->handle, rxHeader->type, rxHeader->transaction,
              rxHeader->error, rxHeader->command);
  }

  if (chppDatagramLenIsOk(context, rxHeader, len)) {
    if (rxHeader->handle == CHPP_HANDLE_NONE) {
      chppDispatchNonHandle(context, buf, len);

    } else if (rxHeader->handle < CHPP_HANDLE_NEGOTIATED_RANGE_START) {
      chppProcessPredefinedHandleDatagram(context, buf, len);

    } else {
      chppProcessNegotiatedHandleDatagram(context, buf, len);
    }
  }

  chppAppProcessDoneCb(context->transportContext, buf);
}

void chppUuidToStr(const uint8_t uuid[CHPP_SERVICE_UUID_LEN],
                   char strOut[CHPP_SERVICE_UUID_STRING_LEN]) {
  snprintf(
      strOut, CHPP_SERVICE_UUID_STRING_LEN,
      "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
      uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
      uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14],
      uuid[15]);
}
