/**
 * When receive connect_frontend command from frontend, change client status that
 * the account and password are stored to property, and start timer.
 * @param client Frontend that passed this request.
 * @param param Parameter contain account, password, frontend type.
 */
void FrontendConnector::recv_connect_frontend(uv_pipe_t& client, picojson::object& param) {
  const std::string& type = param.at("type").get<std::string>();
  const std::string& account  = param.at("account").get<std::string>();
  const std::string& password = param.at("password").get<std::string>();
  FrontendProperty& property = properties.at(&client);

  assert(property.status == PipeStatus::SETUP);
  assert(!account.empty() && !password.empty());

  if (type == "gui") {
    property.type = FrontendType::GUI;

  } else if (type == "cui") {
    property.type = FrontendType::CUI;

  } else {
    /// @todo error
    assert(false);
  }

  property.account  = account;
  property.password = password;

  if (!connect_timer_enable) {
    uv_timer_start(&connect_timer, on_connect_timer, 0, 1000);
    connect_timer_enable = true;
  }
}
/**
 * When receive command from frontend, relay to capable module.
 * @param client Frontend that passed this request.
 * @param content Data contain target module, pid, content of command.
 */
void FrontendConnector::recv_relay_command(uv_pipe_t& client, picojson::object& content) {
  CommandPacket packet = {
    Convert::json2vpid(content.at("pid")),
    Convert::json2nid(content.at("dst_nid")),
    NID::NONE,
    Convert::json2int<Module::Type>(content.at("module")),
    content.at("content").get<picojson::object>()
  };

  Router& router = Router::get_instance();
  router.relay_command(packet, false);
}
/**
 * When receive data, call capable methods.
 * @param client Frontend pipe that send this packet.
 * @param data Packet.
 */
void FrontendConnector::on_recv_data(uv_pipe_t& client, picojson::object& data) {
  const std::string& command = data.at("command").get<std::string>();

  if (command == "relay_command") {
    recv_relay_command(client, data);

  } else if (command == "connect_frontend") {
    recv_connect_frontend(client, data);

  } else if (command == "open_file") {
    recv_open_file(client, data);

  } else {
    /// @todo error
    assert(false);
  }
}
/**
 * When receive open_file command from frontend, pass capable method on Router.
 * @param client Frontend that passed this request.
 * @param param Parameter contain a filename to open.
 */
void FrontendConnector::recv_open_file(uv_pipe_t& client, picojson::object& param) {
  Router& router = Router::get_instance();

  router.load_llvm(param.at("filename").get<std::string>(), std::vector<std::string>());
}