#include "host/libs/allocd/alloc_utils.h"

#include <cstdint>
#include <fstream>

#include "android-base/logging.h"

namespace cuttlefish {

int RunExternalCommand(const std::string& command) {
  FILE* fp;
  LOG(INFO) << "Running external command: " << command;
  fp = popen(command.c_str(), "r");

  if (fp == nullptr) {
    LOG(WARNING) << "Error running external command";
    return -1;
  }

  int status = pclose(fp);
  int ret = -1;
  if (status == -1) {
    LOG(WARNING) << "pclose error";
  } else {
    if (WIFEXITED(status)) {
      LOG(INFO) << "child process exited normally";
      ret = WEXITSTATUS(status);
    } else if (WIFSIGNALED(status)) {
      LOG(WARNING) << "child process was terminated by a signal";
    } else {
      LOG(WARNING) << "child process did not terminate normally";
    }
  }
  return ret;
}

bool AddTapIface(const std::string& name) {
  std::stringstream ss;
  ss << "ip tuntap add dev " << name << " mode tap group cvdnetwork vnet_hdr";
  auto add_command = ss.str();
  LOG(INFO) << "Create tap interface: " << add_command;
  int status = RunExternalCommand(add_command);
  return status == 0;
}

bool ShutdownIface(const std::string& name) {
  std::stringstream ss;
  ss << "ip link set dev " << name << " down";
  auto link_command = ss.str();
  LOG(INFO) << "Shutdown tap interface: " << link_command;
  int status = RunExternalCommand(link_command);

  return status == 0;
}

bool BringUpIface(const std::string& name) {
  std::stringstream ss;
  ss << "ip link set dev " << name << " up";
  auto link_command = ss.str();
  LOG(INFO) << "Bring up tap interface: " << link_command;
  int status = RunExternalCommand(link_command);

  return status == 0;
}

bool CreateEthernetIface(const std::string& name, const std::string& bridge_name,
                         bool has_ipv4_bridge, bool has_ipv6_bridge,
                         bool use_ebtables_legacy) {
  // assume bridge exists

  EthernetNetworkConfig config{false, false, false};

  if (!CreateTap(name)) {
    return false;
  }

  config.has_tap = true;

  if (!LinkTapToBridge(name, bridge_name)) {
    CleanupEthernetIface(name, config);
    return false;
  }

  if (!has_ipv4_bridge) {
    if (!CreateEbtables(name, true, use_ebtables_legacy)) {
      CleanupEthernetIface(name, config);
      return false;
    }
    config.has_broute_ipv4 = true;
  }

  if (!has_ipv6_bridge) {
    if (CreateEbtables(name, false, use_ebtables_legacy)) {
      CleanupEthernetIface(name, config);
      return false;
    }
    config.has_broute_ipv6 = true;
  }

  return true;
}

std::string MobileGatewayName(const std::string& ipaddr, uint16_t id) {
  std::stringstream ss;
  ss << ipaddr << "." << (4 * id + 1);
  return ss.str();
}

std::string MobileNetworkName(const std::string& ipaddr,
                              const std::string& netmask, uint16_t id) {
  std::stringstream ss;
  ss << ipaddr << "." << (4 * id) << netmask;
  return ss.str();
}

bool CreateMobileIface(const std::string& name, uint16_t id,
                       const std::string& ipaddr) {
  if (id > kMaxIfaceNameId) {
    LOG(ERROR) << "ID exceeds maximum value to assign a netmask: " << id;
    return false;
  }

  auto netmask = "/30";
  auto gateway = MobileGatewayName(ipaddr, id);
  auto network = MobileNetworkName(ipaddr, netmask, id);

  if (!CreateTap(name)) {
    return false;
  }

  if (!AddGateway(name, gateway, netmask)) {
    DestroyIface(name);
  }

  if (!IptableConfig(network, true)) {
    DestroyGateway(name, gateway, netmask);
    DestroyIface(name);
    return false;
  };

  return true;
}

bool DestroyMobileIface(const std::string& name, uint16_t id,
                        const std::string& ipaddr) {
  if (id > 63) {
    LOG(ERROR) << "ID exceeds maximum value to assign a netmask: " << id;
    return false;
  }

  auto netmask = "/30";
  auto gateway = MobileGatewayName(ipaddr, id);
  auto network = MobileNetworkName(ipaddr, netmask, id);

  IptableConfig(network, false);
  DestroyGateway(name, gateway, netmask);
  return DestroyIface(name);
}

bool AddGateway(const std::string& name, const std::string& gateway,
                const std::string& netmask) {
  std::stringstream ss;
  ss << "ip addr add " << gateway << netmask << " broadcast + dev " << name;
  auto command = ss.str();
  LOG(INFO) << "setup gateway: " << command;
  int status = RunExternalCommand(command);

  return status == 0;
}

bool DestroyGateway(const std::string& name, const std::string& gateway,
                    const std::string& netmask) {
  std::stringstream ss;
  ss << "ip addr del " << gateway << netmask << " broadcast + dev " << name;
  auto command = ss.str();
  LOG(INFO) << "removing gateway: " << command;
  int status = RunExternalCommand(command);

  return status == 0;
}

bool DestroyEthernetIface(const std::string& name, bool has_ipv4_bridge,
                          bool has_ipv6_bridge, bool use_ebtables_legacy) {
  if (!has_ipv6_bridge) {
    DestroyEbtables(name, false, use_ebtables_legacy);
  }

  if (!has_ipv4_bridge) {
    DestroyEbtables(name, true, use_ebtables_legacy);
  }

  return DestroyIface(name);
}

void CleanupEthernetIface(const std::string& name,
                          const EthernetNetworkConfig& config) {
  if (config.has_broute_ipv6) {
    DestroyEbtables(name, false, config.use_ebtables_legacy);
  }

  if (config.has_broute_ipv4) {
    DestroyEbtables(name, true, config.use_ebtables_legacy);
  }

  if (config.has_tap) {
    DestroyIface(name);
  }
}

bool CreateEbtables(const std::string& name, bool use_ipv4,
                    bool use_ebtables_legacy) {
  return EbtablesBroute(name, use_ipv4, true, use_ebtables_legacy) &&
         EbtablesFilter(name, use_ipv4, true, use_ebtables_legacy);
}

bool DestroyEbtables(const std::string& name, bool use_ipv4,
                     bool use_ebtables_legacy) {
  return EbtablesBroute(name, use_ipv4, false, use_ebtables_legacy) &&
         EbtablesFilter(name, use_ipv4, false, use_ebtables_legacy);
}

bool EbtablesBroute(const std::string& name, bool use_ipv4, bool add,
                    bool use_ebtables_legacy) {
  std::stringstream ss;
  // we don't know the name of the ebtables program, but since we're going to
  // exec this program name, make sure they can only choose between the two
  // options we currently support, and not something they can overwrite
  if (use_ebtables_legacy) {
    ss << kEbtablesLegacyName;
  } else {
    ss << kEbtablesName;
  }

  ss << " -t broute " << (add ? "-A" : "-D") << " BROUTING -p "
     << (use_ipv4 ? "ipv4" : "ipv6") << " --in-if " << name << " -j DROP";
  auto command = ss.str();
  int status = RunExternalCommand(command);

  return status == 0;
}

bool EbtablesFilter(const std::string& name, bool use_ipv4, bool add,
                    bool use_ebtables_legacy) {
  std::stringstream ss;
  if (use_ebtables_legacy) {
    ss << kEbtablesLegacyName;
  } else {
    ss << kEbtablesName;
  }

  ss << " -t filter " << (add ? "-A" : "-D") << " FORWARD -p "
     << (use_ipv4 ? "ipv4" : "ipv6") << " --out-if " << name << " -j DROP";
  auto command = ss.str();
  int status = RunExternalCommand(command);

  return status == 0;
}

bool LinkTapToBridge(const std::string& tap_name,
                     const std::string& bridge_name) {
  std::stringstream ss;
  ss << "ip link set dev " << tap_name << " master " << bridge_name;
  auto command = ss.str();
  int status = RunExternalCommand(command);

  return status == 0;
}

bool CreateTap(const std::string& name) {
  LOG(INFO) << "Attempt to create tap interface: " << name;
  if (!AddTapIface(name)) {
    LOG(WARNING) << "Failed to create tap interface: " << name;
    return false;
  }

  if (!BringUpIface(name)) {
    LOG(WARNING) << "Failed to bring up tap interface: " << name;
    DeleteIface(name);
    return false;
  }

  return true;
}

bool DeleteIface(const std::string& name) {
  std::stringstream ss;
  ss << "ip link delete " << name;
  auto link_command = ss.str();
  LOG(INFO) << "Delete tap interface: " << link_command;
  int status = RunExternalCommand(link_command);

  return status == 0;
}

bool DestroyIface(const std::string& name) {
  if (!ShutdownIface(name)) {
    LOG(WARNING) << "Failed to shutdown tap interface: " << name;
    // the interface might have already shutdown ... so ignore and try to remove
    // the interface. In the future we could read from the pipe and handle this
    // case more elegantly
  }

  if (!DeleteIface(name)) {
    LOG(WARNING) << "Failed to delete tap interface: " << name;
    return false;
  }

  return true;
}

std::optional<std::string> GetUserName(uid_t uid) {
  passwd* pw = getpwuid(uid);
  if (pw) {
    std::string ret(pw->pw_name);
    return ret;
  }
  return std::nullopt;
}

bool CreateBridge(const std::string& name) {
  std::stringstream ss;
  ss << "ip link add name " << name
     << " type bridge forward_delay 0 stp_state 0";

  auto command = ss.str();
  LOG(INFO) << "create bridge: " << command;
  int status = RunExternalCommand(command);

  if (status != 0) {
    return false;
  }

  return BringUpIface(name);
}

bool DestroyBridge(const std::string& name) { return DeleteIface(name); }

bool SetupBridgeGateway(const std::string& bridge_name,
                        const std::string& ipaddr) {
  GatewayConfig config{false, false, false};
  auto gateway = ipaddr + ".1";
  auto netmask = "/24";
  auto network = ipaddr + ".0" + netmask;
  auto dhcp_range = ipaddr + ".2," + ipaddr + ".255";

  if (!AddGateway(bridge_name, gateway, netmask)) {
    return false;
  }

  config.has_gateway = true;

  if (StartDnsmasq(bridge_name, gateway, dhcp_range)) {
    CleanupBridgeGateway(bridge_name, ipaddr, config);
    return false;
  }

  config.has_dnsmasq = true;

  auto ret = IptableConfig(network, true);
  if (!ret) {
    CleanupBridgeGateway(bridge_name, ipaddr, config);
    LOG(WARNING) << "Failed to setup ip tables";
  }

  return ret;
}

void CleanupBridgeGateway(const std::string& name, const std::string& ipaddr,
                          const GatewayConfig& config) {
  auto gateway = ipaddr + ".1";
  auto netmask = "/24";
  auto network = ipaddr + ".0" + netmask;
  auto dhcp_range = ipaddr + ".2," + ipaddr + ".255";

  if (config.has_iptable) {
    IptableConfig(network, false);
  }

  if (config.has_dnsmasq) {
    StopDnsmasq(name);
  }

  if (config.has_gateway) {
    DestroyGateway(name, gateway, netmask);
  }
}

bool StartDnsmasq(const std::string& bridge_name, const std::string& gateway,
                  const std::string& dhcp_range) {
  auto dns_servers = "8.8.8.8,8.8.4.4";
  auto dns6_servers = "2001:4860:4860::8888,2001:4860:4860::8844";
  std::stringstream ss;

  // clang-format off
  ss << 
  "dnsmasq"
    " --port=0"
    " --strict-order"
    " --except-interface=lo"
    " --interface=" << bridge_name << 
    " --listen-address=" << gateway << 
    " --bind-interfaces"
    " --dhcp-range=" << dhcp_range << 
    " --dhcp-option=\"option:dns-server," << dns_servers << "\""
    " --dhcp-option=\"option6:dns-server," << dns6_servers << "\""
    " --conf-file=\"\""
    " --pid-file=/var/run/cuttlefish-dnsmasq-" << bridge_name << ".pid"
    " --dhcp-leasefile=/var/run/cuttlefish-dnsmasq-" << bridge_name << ".leases"
    " --dhcp-no-override ";
  // clang-format on

  auto command = ss.str();
  LOG(INFO) << "start_dnsmasq: " << command;
  int status = RunExternalCommand(command);

  return status == 0;
}

bool StopDnsmasq(const std::string& name) {
  std::ifstream file;
  std::string filename = "/var/run/cuttlefish-dnsmasq-" + name + ".pid";
  LOG(INFO) << "stopping dsnmasq for interface: " << name;
  file.open(filename);
  if (file.is_open()) {
    LOG(INFO) << "dnsmasq file:" << filename
              << " could not be opened, assume dnsmaq has already stopped";
    return true;
  }

  std::string pid;
  file >> pid;
  file.close();
  std::string command = "kill " + pid;
  int status = RunExternalCommand(command);
  auto ret = (status == 0);

  if (ret) {
    LOG(INFO) << "dsnmasq for:" << name << "successfully stopped";
  } else {
    LOG(WARNING) << "Failed to stop dsnmasq for:" << name;
  }
  return ret;
}

bool IptableConfig(const std::string& network, bool add) {
  std::stringstream ss;
  ss << "iptables -t nat " << (add ? "-A" : "-D") << " POSTROUTING -s "
     << network << " -j MASQUERADE";

  auto command = ss.str();
  LOG(INFO) << "iptable_config: " << command;
  int status = RunExternalCommand(command);

  return status == 0;
}

bool CreateEthernetBridgeIface(const std::string& name,
                               const std::string& ipaddr) {
  if (!CreateBridge(name)) {
    return false;
  }

  if (!SetupBridgeGateway(name, ipaddr)) {
    DestroyBridge(name);
    return false;
  }

  return true;
}

bool DestroyEthernetBridgeIface(const std::string& name,
                                const std::string& ipaddr) {
  GatewayConfig config{true, true, true};

  // Don't need to check if removing some part of the config failed, we need to
  // remove the entire interface, so just ignore any error until the end
  CleanupBridgeGateway(name, ipaddr, config);

  return DestroyBridge(name);
}

}  // namespace cuttlefish
