# Path: hippiehug-package/hippiehug/Chain.py
# class DocChain(Chain):
#     """A chain that stores hashes of documents. Construct like a *Chain*."""
# 
#     def multi_add(self, items):
#         """Add multiple items to seal a new block."""
# 
#         docs = list(map(Document, items))
#         for d in docs:
#             self.store[d.hid] = d
# 
#         docs_id = list(map(lambda d: d.hid, docs))
#         Chain.multi_add(self, docs_id)
# 
#     def get(self, block_index, item_index, evidence=None):
#         """Get a sealed item, and optionally a bundle of evidence."""
# 
#         ## Get Doc and check its hash
#         item = Chain.get(self, block_index, item_index, evidence)
#         d = self.store[item]
#         check_hash(item, d)
# 
#         if evidence != None:
#             evidence[d.hid] = d
# 
#         return self.store[item].item
# 
#     def check(self, root, block_index, item_index, item):
#         """Check that an item is within the structure at a specific point."""
#         ret = True
#         ret = ret and (self.root() == root)
#         ret = ret and (self.get(block_index, item_index) == item)
#         return ret
# 
# class Document:
#     __slots__ = ["item", "hid"]
# 
#     def __init__(self, item):
#         self.item = item
#         """ The item stored in the Leaf. """
# 
#         self.hid = binary_hash(packb(("D", self.item)))
# 
#     def identity(self):
#         """ Returns the hash ID of the Leaf. """
#         return self.hid
# 
#     def __eq__(self, other):
#         return self.hid == other.hid
# 
# class Block:
#     def __init__(self, items, index=0, fingers=None, aux=None):
#         """Initialize a block."""
#         self.items = deepcopy(items)
#         self.index = index
#         self.fingers = deepcopy(fingers) if fingers else []
#         self.aux = deepcopy(aux)
# 
#     def hash(self):
#         """Return the head of the block."""
#         return binary_hash(packb(
#                 ("S", self.index, self.fingers, sort_dicts(self.items), self.aux)))
# 
#     @property
#     def hid(self):
#         return self.hash()
# 
#     def next_block(self, store, items, pre_commit_fn=None):
#         """Build a subsequent block, sealing a list of transactions.
# 
#         :param store: Backend
#         :param items: Block items
#         :param pre_commit_fn: Function that gets called on the block before
#                 it gets committed to the chain.
#         """
#         new_index = self.index + 1
#         new_fingers = [(self.index, self.hid)]
# 
#         finger_index = get_fingers(new_index)
#         new_fingers += [f for f in self.fingers if f[0] in finger_index]
# 
#         new_b = Block(items, new_index, new_fingers)
# 
#         if pre_commit_fn is not None:
#             pre_commit_fn(new_b)
# 
#         store[new_b.hid] = new_b
#         return new_b
# 
#     def get_item(self, store, block_index, item_index, evidence=None):
#         """Return an item from the chain at a specific block and item index.
# 
#         :param store: Backend
#         :param block_index: Block index
#         :param item_index: Item index
#         :param evidence: If not None, return a bundle of evidence
#         """
#         # print "FIND: %s (%s, %s)" % (self.index, block_index, item_index)
# 
#         if not (0 <= block_index <= self.index):
#             raise Exception("Block is beyond this chain head: must be 0 <= %s <= %s." % (block_index, self.index))
# 
#         if evidence != None:
#             evidence[self.hid] = self
# 
#         if block_index == self.index:
#             if not (0 <= item_index < len(self.items)):
#                raise Exception("Item is beyond this Block: must be 0 <= %s <= %s." % (item_index, len(self.items)))
# 
#             return self.items[item_index]
# 
#         _, target_h = [(f,block_hash) for (f, block_hash) in self.fingers if f >= block_index][-1]
# 
#         # Get the target block and check its integrity
#         target_block = store[target_h]
#         check_hash(target_h, target_block)
# 
#         return target_block.get_item(store, block_index, item_index, evidence)
# 
#     def __eq__(self, other):
#         return self.hid == other.hid
# 
# Path: hippiehug-package/hippiehug/Utils.py
# def ascii_hash(item):
#     """
#     >>> ascii_hash(b'value')[:4] == b'cd42'
#     True
#     """
#     return hexlify(binary_hash(item))


from .Chain import DocChain, Document, Block
from .Utils import ascii_hash
from binascii import hexlify
from os import urandom
from json import dumps, loads
    from Queue import Queue as Queue
    from queue import Queue as Queue
from threading import Thread
    import boto3


def xtest_create_bucket():
    test1name = ascii_hash(urandom(16))
    print("Name: %s" % test1name)

    try:
        s3c = S3Chain(test1name+"test")
        s3c2 = S3Chain(test1name+"test")

    except Exception as e:
        raise e
    finally:
        bucket = s3c.bucket
        for key in bucket.objects.all():
            key.delete()
        bucket.delete()

def xtest_create_add():
    test1name = "chainspaceiotest1"
    print("Name: %s" % test1name)

    s3c = S3Chain(test1name+"test")
    s3c.add(["Hello","World"])

    assert s3c.get(0,0) == "Hello"

    evidence = {}
    s3c.get(0,0, evidence)


# Path: hippiehug-package/hippiehug/Chain.py
# class DocChain(Chain):
#     """A chain that stores hashes of documents. Construct like a *Chain*."""
# 
#     def multi_add(self, items):
#         """Add multiple items to seal a new block."""
# 
#         docs = list(map(Document, items))
#         for d in docs:
#             self.store[d.hid] = d
# 
#         docs_id = list(map(lambda d: d.hid, docs))
#         Chain.multi_add(self, docs_id)
# 
#     def get(self, block_index, item_index, evidence=None):
#         """Get a sealed item, and optionally a bundle of evidence."""
# 
#         ## Get Doc and check its hash
#         item = Chain.get(self, block_index, item_index, evidence)
#         d = self.store[item]
#         check_hash(item, d)
# 
#         if evidence != None:
#             evidence[d.hid] = d
# 
#         return self.store[item].item
# 
#     def check(self, root, block_index, item_index, item):
#         """Check that an item is within the structure at a specific point."""
#         ret = True
#         ret = ret and (self.root() == root)
#         ret = ret and (self.get(block_index, item_index) == item)
#         return ret
# 
# class Document:
#     __slots__ = ["item", "hid"]
# 
#     def __init__(self, item):
#         self.item = item
#         """ The item stored in the Leaf. """
# 
#         self.hid = binary_hash(packb(("D", self.item)))
# 
#     def identity(self):
#         """ Returns the hash ID of the Leaf. """
#         return self.hid
# 
#     def __eq__(self, other):
#         return self.hid == other.hid
# 
# class Block:
#     def __init__(self, items, index=0, fingers=None, aux=None):
#         """Initialize a block."""
#         self.items = deepcopy(items)
#         self.index = index
#         self.fingers = deepcopy(fingers) if fingers else []
#         self.aux = deepcopy(aux)
# 
#     def hash(self):
#         """Return the head of the block."""
#         return binary_hash(packb(
#                 ("S", self.index, self.fingers, sort_dicts(self.items), self.aux)))
# 
#     @property
#     def hid(self):
#         return self.hash()
# 
#     def next_block(self, store, items, pre_commit_fn=None):
#         """Build a subsequent block, sealing a list of transactions.
# 
#         :param store: Backend
#         :param items: Block items
#         :param pre_commit_fn: Function that gets called on the block before
#                 it gets committed to the chain.
#         """
#         new_index = self.index + 1
#         new_fingers = [(self.index, self.hid)]
# 
#         finger_index = get_fingers(new_index)
#         new_fingers += [f for f in self.fingers if f[0] in finger_index]
# 
#         new_b = Block(items, new_index, new_fingers)
# 
#         if pre_commit_fn is not None:
#             pre_commit_fn(new_b)
# 
#         store[new_b.hid] = new_b
#         return new_b
# 
#     def get_item(self, store, block_index, item_index, evidence=None):
#         """Return an item from the chain at a specific block and item index.
# 
#         :param store: Backend
#         :param block_index: Block index
#         :param item_index: Item index
#         :param evidence: If not None, return a bundle of evidence
#         """
#         # print "FIND: %s (%s, %s)" % (self.index, block_index, item_index)
# 
#         if not (0 <= block_index <= self.index):
#             raise Exception("Block is beyond this chain head: must be 0 <= %s <= %s." % (block_index, self.index))
# 
#         if evidence != None:
#             evidence[self.hid] = self
# 
#         if block_index == self.index:
#             if not (0 <= item_index < len(self.items)):
#                raise Exception("Item is beyond this Block: must be 0 <= %s <= %s." % (item_index, len(self.items)))
# 
#             return self.items[item_index]
# 
#         _, target_h = [(f,block_hash) for (f, block_hash) in self.fingers if f >= block_index][-1]
# 
#         # Get the target block and check its integrity
#         target_block = store[target_h]
#         check_hash(target_h, target_block)
# 
#         return target_block.get_item(store, block_index, item_index, evidence)
# 
#     def __eq__(self, other):
#         return self.hid == other.hid
# 
# Path: hippiehug-package/hippiehug/Utils.py
# def ascii_hash(item):
#     """
#     >>> ascii_hash(b'value')[:4] == b'cd42'
#     True
#     """
#     return hexlify(binary_hash(item))


# Path: hippiehug-package/hippiehug/S3Chain.py
from .Chain import DocChain, Document, Block
from .Utils import ascii_hash
from binascii import hexlify
from os import urandom
from json import dumps, loads
    from Queue import Queue as Queue
    from queue import Queue as Queue
from threading import Thread
    import boto3



def xtest_create_bucket():
    test1name = ascii_hash(urandom(16))
    print("Name: %s" % test1name)

    try:
        s3c = S3Chain(test1name+"test")
        s3c2 = S3Chain(test1name+"test")

    except Exception as e:
        raise e
    finally:
        bucket = s3c.bucket
        for key in bucket.objects.all():
            key.delete()
        bucket.delete()

def xtest_create_add():
    test1name = "chainspaceiotest1"
    print("Name: %s" % test1name)

    s3c = S3Chain(test1name+"test")
    s3c.add(["Hello","World"])

    assert s3c.get(0,0) == "Hello"

    evidence = {}
    s3c.get(0,0, evidence)


    d = DocChain(evidence, s3c.root())