#include <stdio.h>
#include <unistd.h>
#include <protocol/TBinaryProtocol.h>
#include <transport/TSocket.h>
#include <transport/TTransportUtils.h>
#include "Pos.h"
#include "sha1.h"
#include <iostream>

using namespace std;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;

using namespace pos;

using namespace boost;

int main(int argc, char** argv) {
  if (argc != 2) {
    cout << "Usage: client <host>\n";
    exit(1);
  }
  shared_ptr<TTransport> socket(new TSocket(argv[1], 9090));
  shared_ptr<TTransport> transport(new TFramedTransport(socket));
  shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
  PosClient client(protocol);

  try {
    transport->open();
  } catch(TException & e) {
    std::cerr << e.what() << "\n";
  }

  string s;
  while(1) {
    uint32_t in;
    std::cout << "(0) Exit\n(1) Add card to member\n(2) Register new product\n(3) Buy a product\n(4) Deposit money\n(5) Print balance\n> ";
    std::cin >> in;
    switch(in) {
      case 0: exit(0);
      case 1: {
        string user, card;
        cout << "Username: ";
        cin >> user;
        cout << "Swipe card: ";
        getline(cin,s);
        getline(cin,card);
        client.getSalt(s);
        s = SHA1Hash(s+"balls").toHex();
        client.associateHashWithName(s, card, user);
        break;
      }
      case 4: {
        string user;
        int32_t delta;
        cout << "Username: ";
        cin >> user;
        cout << "Amount to change balance by: ";
        cin >> delta;
        client.getSalt(s);
        s = SHA1Hash(s+"balls").toHex();
        client.doTransactionOnHash(s, user, delta);
        break;
      }
      case 5: {
        string user;
        cout << "Username: ";
        cin >> user;
        cout << "$" << client.getNameAccountBalance(user) << "\n";
        break;
      }
    }
  }



  for (uint32_t i =0; i < 5000; i++) {
    std::string s;
    client.getSalt(s);
    s = SHA1Hash(s + "balls").toHex();
    client.doTransactionOnName(s, "j3parker", 1);
  }


  cout << "j3parker balance: " << client.getNameAccountBalance("j3parker") << "\n";
  cout << "m4burns balance: " << client.getNameAccountBalance("m4burns") << "\n";

  return 0;
}

