#include "signing.h"

#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <iostream>

#include "adb.h"

using namespace std;


static int System(const string& command) {
  return system(command.c_str());
}

static int System(const string& command, string& response) {
  const int kBufSize = 1024;
  char buf[kBufSize];
  FILE *p = popen(command.c_str(), "r");
  if (!p) {
    response.empty();
    cerr << "Error in pipe opening" << endl;
    return 1;
  }

  if (fgets(buf, kBufSize, p) == NULL) {
    response.empty();
    pclose(p);
    cerr << "Error in reading from buffer" << endl;
    return 1;
  }
  response.assign(buf);

  pclose(p);
  return 0;
}

static string TrimRight(string &s) {
  return s.substr(0, s.find_last_not_of(" \t"));
}

int Signing::FivePush(const string& path, bool isUserPa) {
  string command = "../tools/five_push.sh ";
  if (isUserPa) {
    command += "--user ";
  }

  command += path;
  command += " -d /vendor/bin";

  return System(command);
}

int Signing::SetXattr(const string& file, const string& name, const string& b64_xattr) {
  const string command = "xattr_manager --name=" + name + " --value=" + b64_xattr + " " + file;
  return Adb::Shell(command);
}

int Signing::GetXattr(const string& file, const string& name, string& b64_xattr) {
  const string command = "xattr_manager --name=" + name + " -d " + file;

  int res = Adb::Shell(command, b64_xattr);

  b64_xattr = TrimRight(b64_xattr);

  return res;
}

int Signing::PaNativeSignature(const string& path, const string& five, string& signature) {
  const string pa_command = "../out/host/pa_signer/pa_signer --cmd sign --key ../config/pa/root_eng_private.key ";
  const string to_run = pa_command + "--path " + path + " --five-sig " + five + " | awk '{print $2}'";

  int ret = System(to_run, signature);
  if (ret) {
    cerr << "Error in pa_signer" << endl;
    return ret;
  }

  signature = TrimRight(signature);

  return 0;
}

int Signing::PaAndroidSignature(const std::string& package, const std::string& five, std::string& signature) {
  const string pa_command =
      "../out/host/pa_signer/pa_signer --cmd sign "
      "--path fake_path "
      "--key ../config/pa/root_eng_private.key "
      "--pkg-key=../config/android_keystore/CERT.RSA ";
  const string to_run = pa_command + "--pkg-name " + package + " --five-sig " + five + " | awk '{print $2}'";

  int ret = System(to_run, signature);
  if (ret) {
    cerr << "Error in pa_signer" << endl;
    return ret;
  }

  signature = TrimRight(signature);

  return 0;
}
