#ifndef _POS_DB_H_
#define _POS_DB_H_
#include "common.h"
#include "sha1.h"
#include "log.h"
#include <list>
#include <map>
#include <string>

class PosDb {
public:
	PosDb(const char * fn);
	uint32_t getAccountFromHash(const SHA1Hash & hash);
	std::list<std::string> getHashesFromAccount(uint32_t account);
	std::list<std::string> getHashesFromAccount(std::string account);

	int32_t getAccountBalance(const SHA1Hash & hash);
	int32_t getAccountBalance(uint32_t account);
	int32_t getAccountBalance(std::string account);

	uint64_t associateHash(const SHA1Hash & hash, uint32_t account);
	uint64_t associateHash(const SHA1Hash & hash, std::string account);
	uint64_t deassociateHash(const SHA1Hash & hash);

	uint64_t doTransaction(const SHA1Hash & hash, int32_t delta);
	uint64_t doTransaction(const uint32_t account, int32_t delta);
	uint64_t doTransaction(std::string account, int32_t delta);
	uint64_t revertTransaction(uint64_t serial);

  int32_t getUPCPrice(UPC upc);
  uint64_t setUPCPrice(UPC upc, int32_t price);

  int32_t getStock(UPC upc);
	uint64_t doStockChange(UPC upc, int32_t delta);

  std::string getUPCName(UPC upc);
  uint64_t setUPCName (UPC upc, std::string name);

  std::vector<std::string> toString();

private:
	void acceptLogEntry(const LogEntry & l);

	std::multimap<uint32_t, SHA1Hash> account_to_hash;
	std::map<uint32_t, int32_t> account_to_balance;

	std::map<UPC, int32_t, UPCLess> upc_to_stock;
  std::map<UPC, int32_t, UPCLess> upc_to_price;
  std::map<UPC, std::string, UPCLess> upc_to_name;

	std::map<uint64_t, LogEntry> serial_to_object;

	Log log;
};

typedef std::multimap<uint32_t, SHA1Hash>::iterator ath_it;
typedef std::map<uint32_t, int32_t>::iterator atb_it;
typedef std::map<UPC, int32_t, UPCLess>::iterator uts_it;
typedef std::map<uint64_t, LogEntry>::iterator sto_it;
typedef std::pair<ath_it, ath_it> ath_it_r;

#endif

