__author__ = 'frank'

import json

from BaseObject import BaseObject
from Requestor import process_request


class WalletName(BaseObject):
    """
    Wallet Name object

    :param domain_name: Domain name that Wallet Name should be associated with.
    :param name: Unique name for this Wallet Name prefixed to your domain_name. e.g. name.domain_name
    :param external_id: Unique identifier of your choice to identify your user's Wallet Name.
    :param id: Unique Netki identifier for this Wallet Name.
    """

    def __init__(self, domain_name, name, external_id, id=None):
        super(WalletName, self).__init__()

        self.domain_name = domain_name
        self.name = name
        self.external_id = external_id
        self.id = id
        self.wallets = {}

    def get_used_currencies(self):
        """
        Returns wallets dictionary containing currencies and wallet addresses.
        ``wallets['currency']: 'wallet_address'``
        """
        return self.wallets

    def get_wallet_address(self, currency):
        """ Returns the wallet address for a provided currency. """
        return self.wallets[currency]

    def set_currency_address(self, currency, wallet_address):
        """
        Create or update a currency and wallet address.

        :param currency: Three or Four letter currency identifier per Netki API documentation. ``btc, ltc, oap``
        :param wallet_address: wallet address for provided currency
        """
        self.wallets[currency] = wallet_address

    def remove_currency_address(self, currency):
        """ Remove a currency including the associated wallet address. """
        if self.wallets[currency]:
            del self.wallets[currency]

    def save(self):
        """
        Commit changes to a WalletName object by submitting them to the API. For new Wallet Names, an id will
        automatically be generated by the server. Run Netki.create_wallet_name() to create a new WalletName object,
        then run save() on your WalletName object to submit it to the API. To update a Wallet Name, run
        Netki.get_wallet_names() to retrieve the Wallet Name object, make your updates, then run save() on the
        WalletName object to commit changes to the API.
        """

        wallet_data = []

        for k in self.wallets.keys():
            wallet_data.append({
                'currency': k,
                'wallet_address': self.wallets[k]
            })

        wallet_name_data = {
            'domain_name': self.domain_name,
            'name': self.name,
            'wallets': wallet_data,
            'external_id': self.external_id
        }

        wn_api_data = {'wallet_names': [wallet_name_data]}

        # If an ID is present it exists in Netki's systems, therefore submit an update
        if self.id:
            wallet_name_data['id'] = self.id
            response = process_request(
                self.netki_client,
                '/v1/partner/walletname',
                'PUT',
                wn_api_data
            )
        else:
            response = process_request(
                self.netki_client,
                '/v1/partner/walletname',
                'POST',
                wn_api_data
            )

        for wn in response.wallet_names:
            if wn.domain_name == self.domain_name and wn.name == self.name:
                self.id = wn.id

    def delete(self):
        """
        To delete a WalletName object, first run Netki.get_wallet_names() to retrieve the Wallet Name from the API,
        then run delete() on the WalletName object to delete it from Netki systems.
        """

        if not self.id:
            raise Exception('Unable to Delete Object that Does Not Exist Remotely')

        wn_api_data = {
            'wallet_names': [
                {
                    'domain_name': self.domain_name,
                    'id': self.id
                }
            ]
        }

        process_request(
            self.netki_client,
            '/v1/partner/walletname',
            'DELETE',
            wn_api_data
        )
