#include "Utils.h"

#include <fstream>
#include <stdexcept>
#include <openssl/sha.h>

#include "base64_decode.h"
#include "base64_encode.h"

using namespace std;

vector<uint8_t> ReadFile(const string& filename) {
  basic_ifstream<uint8_t> file(filename.c_str(), ios::binary);
  streamsize size = file.tellg();
  file.seekg(0, ios::beg);

  vector<uint8_t> buffer(size);
  if (file.read(buffer.data(), size)) {
    return buffer;
  } else {
    throw runtime_error("ReadFile: Can't read file: " + filename);
  }
}

vector<uint8_t> Sha256(const vector<uint8_t>& data) {
  vector<uint8_t> hash(SHA256_DIGEST_LENGTH);

  SHA256(&data[0], data.size(), &hash[0]);

  return hash;
}

vector<uint8_t> Base64Decode(const string& input) {
  vector<uint8_t> result(input.size());
  size_t output_size = result.size();

  int error_code = base64decode(input.c_str(), input.size(), &result[0],
                                &output_size);

  result.resize(error_code ? 0 : output_size);

  return result;
}

string Base64Encode(const vector<uint8_t>& input) {
  vector<string::value_type> result(input.size() * 2);

  int error_code = base64encode(&input[0], input.size(), &result[0],
                                result.size());

  return (error_code ? "" : &result[0]);
}

vector<uint8_t> StringToVector(const string& string) {
  vector<uint8_t> result(string.c_str(), string.c_str() + string.size());
  return result;
}
