/*
 * Copyright (C) 2017 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 <cinttypes>
#include <type_traits>

#include "chre/core/event_loop_manager.h"
#include "chre/core/host_comms_manager.h"
#include "chre/platform/assert.h"
#include "chre/platform/host_link.h"

namespace chre {

constexpr uint32_t kMessageToHostReservedFieldValue = UINT32_MAX;

bool HostCommsManager::sendMessageToHostFromNanoapp(
    Nanoapp *nanoapp, void *messageData, size_t messageSize,
    uint32_t messageType, uint16_t hostEndpoint,
    chreMessageFreeFunction *freeCallback) {
  bool success = false;
  if (messageSize > 0 && messageData == nullptr) {
    LOGW("Rejecting malformed message (null data but non-zero size)");
  } else if (messageSize > CHRE_MESSAGE_TO_HOST_MAX_SIZE) {
    LOGW("Rejecting message of size %zu bytes (max %d)", messageSize,
         CHRE_MESSAGE_TO_HOST_MAX_SIZE);
  } else if (hostEndpoint == kHostEndpointUnspecified) {
    LOGW("Rejecting message to invalid host endpoint");
  } else {
    MessageToHost *msgToHost = mMessagePool.allocate();

    if (msgToHost == nullptr) {
      LOG_OOM();
    } else {
      msgToHost->appId = nanoapp->getAppId();
      msgToHost->message.wrap(static_cast<uint8_t *>(messageData), messageSize);
      msgToHost->toHostData.hostEndpoint = hostEndpoint;
      msgToHost->toHostData.messageType = messageType;
      msgToHost->toHostData.nanoappFreeFunction = freeCallback;

      // Populate a special value to help disambiguate message direction when
      // debugging
      msgToHost->toHostData.reserved = kMessageToHostReservedFieldValue;

      // Let the nanoapp know that it woke up the host and record it
      bool hostWasAwake = EventLoopManagerSingleton::get()
                              ->getEventLoop()
                              .getPowerControlManager()
                              .hostIsAwake();

      success = HostLink::sendMessage(msgToHost);
      if (!success) {
        mMessagePool.deallocate(msgToHost);
      } else if (!hostWasAwake && !mIsNanoappBlamedForWakeup) {
        // If message successfully sent and host was suspended before sending
        EventLoopManagerSingleton::get()
            ->getEventLoop()
            .handleNanoappWakeupBuckets();
        mIsNanoappBlamedForWakeup = true;
        nanoapp->blameHostWakeup();
      }
    }
  }

  return success;
}

MessageFromHost *HostCommsManager::craftNanoappMessageFromHost(
    uint64_t appId, uint16_t hostEndpoint, uint32_t messageType,
    const void *messageData, uint32_t messageSize) {
  MessageFromHost *msgFromHost = mMessagePool.allocate();
  if (msgFromHost == nullptr) {
    LOG_OOM();
  } else if (!msgFromHost->message.copy_array(
                 static_cast<const uint8_t *>(messageData), messageSize)) {
    LOGE("Couldn't allocate %" PRIu32
         " bytes for message data from host "
         "(endpoint 0x%" PRIx16 " type %" PRIu32 ")",
         messageSize, hostEndpoint, messageType);
    mMessagePool.deallocate(msgFromHost);
    msgFromHost = nullptr;
  } else {
    msgFromHost->appId = appId;
    msgFromHost->fromHostData.messageType = messageType;
    msgFromHost->fromHostData.messageSize = messageSize;
    msgFromHost->fromHostData.message = msgFromHost->message.data();
    msgFromHost->fromHostData.hostEndpoint = hostEndpoint;
  }

  return msgFromHost;
}

bool HostCommsManager::deliverNanoappMessageFromHost(
    MessageFromHost *craftedMessage) {
  const EventLoop &eventLoop = EventLoopManagerSingleton::get()->getEventLoop();
  uint32_t targetInstanceId;
  bool success = false;

  CHRE_ASSERT_LOG(craftedMessage != nullptr,
                  "Cannot deliver NULL pointer nanoapp message from host");

  if (eventLoop.findNanoappInstanceIdByAppId(craftedMessage->appId,
                                             &targetInstanceId)) {
    success = true;
    if (!EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
            CHRE_EVENT_MESSAGE_FROM_HOST, &craftedMessage->fromHostData,
            freeMessageFromHostCallback, targetInstanceId)) {
      mMessagePool.deallocate(craftedMessage);
    }
  }

  return success;
}

void HostCommsManager::sendMessageToNanoappFromHost(uint64_t appId,
                                                    uint32_t messageType,
                                                    uint16_t hostEndpoint,
                                                    const void *messageData,
                                                    size_t messageSize) {
  if (hostEndpoint == kHostEndpointBroadcast) {
    LOGE("Received invalid message from host from broadcast endpoint");
  } else if (messageSize > ((UINT32_MAX))) {
    // The current CHRE API uses uint32_t to represent the message size in
    // struct chreMessageFromHostData. We don't expect to ever need to exceed
    // this, but the check ensures we're on the up and up.
    LOGE("Rejecting message of size %zu (too big)", messageSize);
  } else {
    MessageFromHost *craftedMessage = craftNanoappMessageFromHost(
        appId, hostEndpoint, messageType, messageData,
        static_cast<uint32_t>(messageSize));
    if (craftedMessage == nullptr) {
      LOGE("Out of memory - rejecting message to app ID 0x%016" PRIx64
           "(size %zu)",
           appId, messageSize);
    } else if (!deliverNanoappMessageFromHost(craftedMessage)) {
      LOGD("Deferring message; destination app ID 0x%016" PRIx64
           " not found at this time",
           appId);

      auto deferredMessageCallback = [](uint16_t /*type*/, void *data) {
        EventLoopManagerSingleton::get()
            ->getHostCommsManager()
            .sendDeferredMessageToNanoappFromHost(
                static_cast<MessageFromHost *>(data));
      };
      EventLoopManagerSingleton::get()->deferCallback(
          SystemCallbackType::DeferredMessageToNanoappFromHost, craftedMessage,
          deferredMessageCallback);
    }
  }
}

void HostCommsManager::sendDeferredMessageToNanoappFromHost(
    MessageFromHost *craftedMessage) {
  CHRE_ASSERT_LOG(craftedMessage != nullptr,
                  "Deferred message from host is a NULL pointer");

  if (!deliverNanoappMessageFromHost(craftedMessage)) {
    LOGE("Dropping deferred message; destination app ID 0x%016" PRIx64
         " still not found",
         craftedMessage->appId);
    mMessagePool.deallocate(craftedMessage);
  } else {
    LOGD("Deferred message to app ID 0x%016" PRIx64 " delivered",
         craftedMessage->appId);
  }
}

void HostCommsManager::resetBlameForNanoappHostWakeup() {
  mIsNanoappBlamedForWakeup = false;
}

void HostCommsManager::onMessageToHostComplete(const MessageToHost *message) {
  // Removing const on message since we own the memory and will deallocate it;
  // the caller (HostLink) only gets a const pointer
  auto *msgToHost = const_cast<MessageToHost *>(message);

  // If there's no free callback, we can free the message right away as the
  // message pool is thread-safe; otherwise, we need to do it from within the
  // EventLoop context.
  if (msgToHost->toHostData.nanoappFreeFunction == nullptr) {
    mMessagePool.deallocate(msgToHost);
  } else {
    auto freeMsgCallback = [](uint16_t /*type*/, void *data) {
      EventLoopManagerSingleton::get()->getHostCommsManager().freeMessageToHost(
          static_cast<MessageToHost *>(data));
    };

    EventLoopManagerSingleton::get()->deferCallback(
        SystemCallbackType::MessageToHostComplete, msgToHost, freeMsgCallback);
  }
}

void HostCommsManager::freeMessageToHost(MessageToHost *msgToHost) {
  if (msgToHost->toHostData.nanoappFreeFunction != nullptr) {
    EventLoopManagerSingleton::get()->getEventLoop().invokeMessageFreeFunction(
        msgToHost->appId, msgToHost->toHostData.nanoappFreeFunction,
        msgToHost->message.data(), msgToHost->message.size());
  }
  mMessagePool.deallocate(msgToHost);
}

void HostCommsManager::freeMessageFromHostCallback(uint16_t /*type*/,
                                                   void *data) {
  // We pass the chreMessageFromHostData structure to the nanoapp as the event's
  // data pointer, but we need to return to the enclosing HostMessage pointer.
  // As long as HostMessage is standard-layout, and fromHostData is the first
  // field, we can convert between these two pointers via reinterpret_cast.
  // These static assertions ensure this assumption is held.
  static_assert(std::is_standard_layout<HostMessage>::value,
                "HostMessage* is derived from HostMessage::fromHostData*, "
                "therefore it must be standard layout");
  static_assert(offsetof(MessageFromHost, fromHostData) == 0,
                "fromHostData must be the first field in HostMessage");

  auto *eventData = static_cast<chreMessageFromHostData *>(data);
  auto *msgFromHost = reinterpret_cast<MessageFromHost *>(eventData);
  auto &hostCommsMgr = EventLoopManagerSingleton::get()->getHostCommsManager();
  hostCommsMgr.mMessagePool.deallocate(msgFromHost);
}

}  // namespace chre
