#include "proca.h"

#include <string>
#include <unistd.h>
#include <sstream>
#include <iostream>

#include "adb.h"


static int RunCommand(const std::string& cmd) {
  std::string run_cmd = cmd;
  run_cmd += " &> /dev/null";

  return Adb::Shell(run_cmd.c_str());
}

bool Proca::KillDaemon() {
  int ret;
  if (Proca::isAndroidHigherThanO()) {
    ret = RunCommand("pkill '^[/]*proca'");
  } else {
    ret = RunCommand("pkill '^[/]*pa_daemon'");
  }

  if (ret) {
    return false;
  }
  sleep(1);

  return true;
}

pid_t Proca::GetDaemonPid() {
  std::string pid_str;
  if (Adb::Shell("ps -A | grep proca| awk '{print \\$2}'", pid_str) != 0) {
    return 0;
  }

  if (pid_str.empty()) {
    return 0;
  }

  pid_t pid;
  std::istringstream(pid_str) >> pid;
  return pid;
}

bool Proca::WaitForDaemon(int seconds) {
  pid_t prev_pid, curr_pid = 0;

  while (seconds > 0) {
    prev_pid = curr_pid;
    curr_pid = GetDaemonPid();
    if (curr_pid != 0 && curr_pid == prev_pid) {
      return true;
    }

    sleep(3);
    seconds -= 3;
  }

  return false;
}

bool Proca::isAndroidHigherThanO() {
  std::string sdk_version_str;

  if (Adb::Shell("getprop ro.build.version.sdk", sdk_version_str) != 0)
    return false;

  int sdk_version;
  std::istringstream(sdk_version_str) >> sdk_version;
  return sdk_version >= 28;
}
