#include "adb.h"

#include <cstdio>
#include <cstdlib>

#include <iostream>

const std::string kAdbShell = "adb shell ";
const std::string kAdbInstallTemplate = "adb install -r ";
const std::string kAdbUninstallTemplate = "adb uninstall ";
const std::string kAdbPush = "adb push ";
const std::string kAdbRemount = "adb remount ";
const std::string kSendToDevNull = "> /dev/null";

static int System(const std::string& command) {
  return system(command.c_str());
}

int Adb::Shell(const std::string& command, std::string& response) {
  std::string to_run = kAdbShell + "\"" + command + "\"";
  const int kBufSize = 1024;
  char buf[kBufSize];
  FILE *p = popen(to_run.c_str(), "r");
  if (!p) {
    response.empty();
    std::cerr << "Error in pipe opening" << std::endl;
    return 1;
  }

  if (fgets(buf, kBufSize, p) == NULL) {
    response.empty();
  } else {
    response.assign(buf);
  }

  return pclose(p);
}

int Adb::Shell(const std::string& command, bool hide_output) {
  std::string to_run = kAdbShell + "\"" + command+ "\"";

  if (hide_output) {
    to_run += kSendToDevNull;
  }

  return System(to_run);
}

int Adb::Install(const std::string& path, bool hide_output) {
  std::string to_run = kAdbInstallTemplate + path;

  if (hide_output) {
    to_run += kSendToDevNull;
  }

  int res = System(to_run);

  Adb::Shell("sync");

  return res;
}

int Adb::Push(const std::string& src, const std::string& dst) {
  std::string to_run = kAdbPush + src + " " + dst;

  int res = System(to_run);

  Adb::Shell("sync");

  return res;
}

int Adb::Remount() {
  return System(kAdbRemount + kSendToDevNull);
}

bool Adb::isFileExists(const std::string &path) {
  return Adb::Shell("ls " + path) == 0;
}

int Adb::Uninstall(const std::string& path, bool hide_output) {
  std::string to_run = kAdbUninstallTemplate + path;

  if (hide_output) {
    to_run += kSendToDevNull;
  }

  int res = System(to_run);

  Adb::Shell("sync");

  return res;
}
