/*
 * 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 "host/ivserver/ivserver.h"

#include <sys/select.h>
#include <algorithm>

#include <glog/logging.h>

#include "common/libs/fs/shared_select.h"
#include "host/ivserver/hald_client.h"
#include "host/ivserver/qemu_client.h"

namespace ivserver {

IVServer::IVServer(const IVServerOptions &options, const Json::Value &json_root)
    : json_root_{json_root},
      vsoc_shmem_(VSoCSharedMemory::New(options.shm_file_path, json_root_)) {
  LOG_IF(WARNING, unlink(options.qemu_socket_path.c_str()) == 0)
      << "Removed existing unix socket: " << options.qemu_socket_path
      << ". We can't confirm yet whether another instance is running.";
  qemu_channel_ = avd::SharedFD::SocketLocalServer(
      options.qemu_socket_path.c_str(), false, SOCK_STREAM, 0666);
  LOG_IF(FATAL, !qemu_channel_->IsOpen())
      << "Could not create QEmu channel: " << qemu_channel_->StrError();

  LOG_IF(WARNING, unlink(options.client_socket_path.c_str()) == 0)
      << "Removed existing unix socket: " << options.client_socket_path
      << ". We can't confirm yet whether another instance is running.";
  client_channel_ = avd::SharedFD::SocketLocalServer(
      options.client_socket_path.c_str(), false, SOCK_STREAM, 0666);
  LOG_IF(FATAL, !client_channel_->IsOpen())
      << "Could not create Client channel: " << client_channel_->StrError();
}

void IVServer::Serve() {
  while (true) {
    avd::SharedFDSet rset;
    rset.Set(qemu_channel_);
    rset.Set(client_channel_);
    avd::Select(&rset, nullptr, nullptr, nullptr);

    if (rset.IsSet(qemu_channel_)) {
      HandleNewQemuConnection();
    }

    if (rset.IsSet(client_channel_)) {
      HandleNewClientConnection();
    }
  }

  LOG(FATAL) << "Control reached out of event loop";
}

void IVServer::HandleNewClientConnection() {
  std::unique_ptr<HaldClient> res = HaldClient::New(
      *vsoc_shmem_, avd::SharedFD::Accept(*client_channel_, nullptr, nullptr));
  if (!res) {
    LOG(WARNING) << "Rejecting unsuccessful HALD connection.";
  }
}

void IVServer::HandleNewQemuConnection() {
  std::unique_ptr<QemuClient> res = QemuClient::New(
      *vsoc_shmem_, avd::SharedFD::Accept(*qemu_channel_, nullptr, nullptr));

  if (!res) {
    LOG(WARNING) << "Could not accept new QEmu client.";
  }
}

}  // namespace ivserver
