/*
 * 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 "common/commands/wifi_relay/nl_client.h"

#include <glog/logging.h>

namespace cvd {

NlClient::NlClient(int nl_type)
    : nl_type_(nl_type),
      callback_(nullptr, [](nl_cb* cb) { free(cb); }),
      sock_(nullptr, [](nl_sock* sock) { free(sock); }) {}

bool NlClient::Init() {
  // Set up netlink callbacks.
  callback_.reset(nl_cb_alloc(NL_CB_CUSTOM));
  if (!callback_) {
    LOG(ERROR) << "Could not create netlink callback.";
    return false;
  }

  // Register callback that will receive asynchronous messages from netlink.
  nl_cb_set(callback_.get(), NL_CB_MSG_IN, NL_CB_CUSTOM,
            [](nl_msg* msg, void* data) {
              NlClient* self = static_cast<NlClient*>(data);
              return self->OnResponse(msg);
            },
            this);

  // Open Netlink target.
  sock_.reset(nl_socket_alloc_cb(callback_.get()));
  if (!sock_) {
    LOG(ERROR) << "Could not create netlink socket. Are you root?";
    return false;
  }

  if (nl_connect(sock_.get(), nl_type_) < 0) {
    LOG(ERROR) << "Could not connect to netlink. Are you root?";
    return false;
  }

  return true;
}

void NlClient::Send(Cmd* msg) {
  std::lock_guard<std::mutex> guard(in_flight_mutex_);
  // nl_send_auto sets sequence number (if defaults to NL_AUTO_SEQ).
  // Make sure to execute this while in critical section to ensure we have time
  // to set up callback before we receive response.
  nl_send_auto(sock_.get(), msg->Msg());
  auto seq = nlmsg_hdr(msg->Msg())->nlmsg_seq;
  in_flight_[seq] = msg;
}

// Handle asynchronous messages & responses from netlink.
int NlClient::OnResponse(nl_msg* msg) {
  nlmsghdr* header = nlmsg_hdr(msg);
  int seq = header->nlmsg_seq;

  // Find & invoke corresponding callback, if any.
  std::lock_guard<std::mutex> guard(in_flight_mutex_);
  auto pos = in_flight_.find(seq);
  if (pos != in_flight_.end()) {
    if (pos->second->OnResponse(msg)) {
      // Erase command if reports it's done.
      in_flight_.erase(seq);
    }
  } else if (default_handler_) {
    default_handler_(msg);
  }

  return NL_OK;
}

void NlClient::SetDefaultHandler(std::function<void(nl_msg*)> cb) {
  std::lock_guard<std::mutex> guard(in_flight_mutex_);
  default_handler_ = std::move(cb);
}

nl_sock* NlClient::Sock() const { return sock_.get(); }

}  // namespace cvd
