/*
 * 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 "host/commands/assemble_cvd/alloc.h"

#include <iomanip>
#include <sstream>

#include "common/libs/fs/shared_fd.h"
#include "host/libs/allocd/request.h"
#include "host/libs/allocd/utils.h"

namespace cuttlefish {

static std::string StrForInstance(const std::string& prefix, int num) {
  std::ostringstream stream;
  stream << prefix << std::setfill('0') << std::setw(2) << num;
  return stream.str();
}

IfaceConfig DefaultNetworkInterfaces(int num) {
  IfaceConfig config{};
  config.mobile_tap.name = StrForInstance("cvd-mtap-", num);
  config.mobile_tap.resource_id = 0;
  config.mobile_tap.session_id = 0;

  config.wireless_tap.name = StrForInstance("cvd-wtap-", num);
  config.wireless_tap.resource_id = 0;
  config.wireless_tap.session_id = 0;

  config.ethernet_tap.name = StrForInstance("cvd-etap-", num);
  config.ethernet_tap.resource_id = 0;
  config.ethernet_tap.session_id = 0;

  return config;
}

std::optional<IfaceConfig> AllocateNetworkInterfaces() {
  IfaceConfig config{};

  SharedFD allocd_sock = SharedFD::SocketLocalClient(
      kDefaultLocation, false, SOCK_STREAM);
  CHECK(allocd_sock->IsOpen())
      << "Unable to connect to allocd on " << kDefaultLocation
      << ": " << allocd_sock->StrError();

  Json::Value resource_config;
  Json::Value request_list;
  Json::Value req;
  req["request_type"] = "create_interface";
  req["uid"] = geteuid();
  req["iface_type"] = "mtap";
  request_list.append(req);
  req["iface_type"] = "wtap";
  request_list.append(req);
  req["iface_type"] = "etap";
  request_list.append(req);

  resource_config["config_request"]["request_list"] = request_list;

  CHECK(SendJsonMsg(allocd_sock, resource_config))
      << "Failed to send JSON to allocd";

  auto resp_opt = RecvJsonMsg(allocd_sock);
  CHECK(resp_opt.has_value()) << "Bad response from allocd";
  auto resp = resp_opt.value();

  CHECK(resp.isMember("config_status") && !resp["config_status"].isString())
      << "Bad response from allocd: " << resp;

  CHECK_EQ(
      resp["config_status"].asString(),
      StatusToStr(RequestStatus::Success))
          <<"Failed to allocate interfaces " << resp;

  CHECK(resp.isMember("session_id") && resp["session_id"].isUInt())
      << "Bad response from allocd: " << resp;
  auto session_id = resp["session_id"].asUInt();

  CHECK(resp.isMember("response_list") && resp["response_list"].isArray())
      << "Bad response from allocd: " << resp;

  Json::Value resp_list = resp["response_list"];
  Json::Value mtap_resp;
  Json::Value wtap_resp;
  Json::Value etap_resp;
  for (Json::Value::ArrayIndex i = 0; i != resp_list.size(); ++i) {
    auto ty = StrToIfaceTy(resp_list[i]["iface_type"].asString());

    switch (ty) {
      case IfaceType::mtap: {
        mtap_resp = resp_list[i];
        break;
      }
      case IfaceType::wtap: {
        wtap_resp = resp_list[i];
        break;
      }
      case IfaceType::etap: {
        etap_resp = resp_list[i];
        break;
      }
      default: {
        break;
      }
    }
  }

  if (!mtap_resp.isMember("iface_type")) {
    LOG(ERROR) << "Missing mtap response from allocd";
    return std::nullopt;
  }
  if (!wtap_resp.isMember("iface_type")) {
    LOG(ERROR) << "Missing wtap response from allocd";
    return std::nullopt;
  }
  if (!etap_resp.isMember("iface_type")) {
    LOG(ERROR) << "Missing etap response from allocd";
    return std::nullopt;
  }

  config.mobile_tap.name = mtap_resp["iface_name"].asString();
  config.mobile_tap.resource_id = mtap_resp["resource_id"].asUInt();
  config.mobile_tap.session_id = session_id;

  config.wireless_tap.name = wtap_resp["iface_name"].asString();
  config.wireless_tap.resource_id = wtap_resp["resource_id"].asUInt();
  config.wireless_tap.session_id = session_id;

  config.ethernet_tap.name = etap_resp["iface_name"].asString();
  config.ethernet_tap.resource_id = etap_resp["resource_id"].asUInt();
  config.ethernet_tap.session_id = session_id;

  return config;
}

} // namespace cuttlefish
