"""
Implementation of Compute Nodes.
"""
from __future__ import print_function
from __future__ import division
from __future__ import unicode_literals


class Node(object):
  """Abstract base class for commpute nodes."""

  def __init__(self, wallet):
    """Initializes the compute node

    Parameters
    ----------
    wallet: dm.coins.Wallet
      Wallets used to store coins for this node.
    """
    raise NotImplementedError

  def compute(self, ledger, ledger_key, computation):
    """Performs the requested computation on requested data.

    Subclasses will need to implement desired operations

    Parameters
    ----------
    ledger:       A record of where the data was stored. Details vary on
                  implementation.
    ledger_key:   An access key that permits reading the data stored in
                  associated ledger.
    computation: A description of the computation to be performed.
    """
    raise NotImplementedError

  def get_wallet(self):
    """Returns access to wallet

    Returns 
    ----------
    wallet: dm.coins.Wallet 
      The wallet associated with this node.
    """
    raise NotImplementedError


class GenomicCountInsecureFileNode(Node):
  """A simple example compute node that counts base pairs in genomic data.

  This compute node is very limited and only computes counts of base-pairs.
  Assumes that data it's given is genomic, and that the data comes from ledgers
  created by InsecureFIleClient. Needless to say, this compute node
  implementation is meant solely for simple demonstrations of concept.
  """

  def __init__(self, wallet):
    """Initializes the compute node

    Parameters
    ----------
    wallet: dm.coins.Wallet
      Wallets used to store coins for this node.
    """
    self.wallet = wallet

    # TODO(rbharath): This increment should be factored out somehow,
    # likely into a solidity contract.
    self.compute_reward = 1

  def compute(self, ledger, ledger_key, computation):
    """Performs the base-pair count.

    Parameters
    ----------
    ledger: Must be generated by InsecureFileClient
    ledger_key: Must be generated by InsecureFileClient
    computation: String
      Must read "count-basepairs"
    """
    with open(ledger) as data_file:
      data = str(data_file.read())
    results = {}
    for base_pair in ["A", "C", "G", "T"]:
      results[base_pair] = data.count(base_pair)
      # TODO(rbharath): This money needs to come from somewhere!!
      self.wallet.deposit(self.compute_reward)
    return results

  def get_wallet(self):
    """Returns access to wallet

    Returns 
    ----------
    wallet: dm.coins.Wallet 
      The wallet associated with this node.
    """
    return self.wallet
