# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.


from crypt import methods
from curses import meta
from .transport import Transport
from .offchain import prepare_transaction, fulfill_transaction
from .utils import normalize_nodes
from typing import Any, Union


class Resdb:
    """! A :class:`~resdb_driver.Resdb` driver is able to create, sign,
    and submit transactions to one or more nodes in a Federation.

    If initialized with ``>1`` nodes, the driver will send successive
    requests to different nodes in a round-robin fashion (this will be
    customizable in the future).

    """

    def __init__(
        self,
        *nodes: list[Union[str, dict]],
        transport_class: Transport = Transport,
        headers=None,
        timeout=20
    ):
        """! Initialize a :class:`~resdb_driver.Resdb` driver instance.

        @param *nodes (list of (str or dict)): Resdb nodes to connect to.
                Currently, the full URL must be given. In the absence of any
                node, the default(``'http://localhost:9984'``) will be used.
                If node is passed as a dict, `endpoint` is a required key;
                `headers` is an optional `dict` of headers.
        @param transport_class Optional transport class to use.
                Defaults to :class:`~resdb_driver.transport.Transport`.
        @param headers (dict): Optional headers that will be passed with
                each request. To pass headers only on a per-request
                basis, you can pass the headers to the method of choice
                (e.g. :meth:`Resdb().transactions.send_commit()
                <.TransactionsEndpoint.send_commit>`).
        @param timeout (int): Optional timeout in seconds that will be passed
                to each request.

        @return An instance of the Resdb class
        """
        self._nodes = normalize_nodes(*nodes, headers=headers)
        self._transport = transport_class(*self._nodes, timeout=timeout)
        self._transactions = TransactionsEndpoint(self)
        self._outputs = OutputsEndpoint(self)
        self._blocks = BlocksEndpoint(self)
        self._assets = AssetsEndpoint(self)
        self._metadata = MetadataEndpoint(self)
        self.api_prefix = "/v1"

    @property
    def nodes(self):
        """! :obj:`tuple` of :obj:`str`: URLs of connected nodes."""
        return self._nodes

    @property
    def transport(self):
        """! :class:`~resdb_driver.transport.Transport`: Object
        responsible for forwarding requests to a
        :class:`~resdb_driver.connection.Connection` instance (node).
        """
        return self._transport

    @property
    def transactions(self):
        """! :class:`~resdb_driver.driver.TransactionsEndpoint`:
        Exposes functionalities of the ``'/transactions'`` endpoint.
        TODO: check
        """
        return self._transactions

    @property
    def outputs(self):
        """! :class:`~resdb_driver.driver.OutputsEndpoint`:
        Exposes functionalities of the ``'/outputs'`` endpoint.
        TODO: check
        """
        return self._outputs

    @property
    def assets(self):
        """! :class:`~resdb_driver.driver.AssetsEndpoint`:
        Exposes functionalities of the ``'/assets'`` endpoint.
        TODO: check
        """
        return self._assets

    @property
    def metadata(self):
        """! :class:`~resdb_driver.driver.MetadataEndpoint`:
        Exposes functionalities of the ``'/metadata'`` endpoint.
        TODO: check
        """
        return self._metadata

    @property
    def blocks(self):
        """! :class:`~resdb_driver.driver.BlocksEndpoint`:
        Exposes functionalities of the ``'/blocks'`` endpoint.
        TODO: check
        """
        return self._blocks

    def info(self, headers=None) -> dict:
        """! Retrieves information of the node being connected to via the
        root endpoint ``'/'``.

        Note:
            TODO: implement the endpoint in the node (Single node)

        @param headers (dict): Optional headers to pass to the request.

        @return Details of the node that this instance is connected
        to. Some information that may be interesting - Server version, overview of all the endpoints
        """

        return self.transport.forward_request(method="GET", path="/", headers=headers)

    def api_info(self, headers=None) -> dict:
        """! Retrieves information provided by the API root endpoint
        ``'/api/v1'``.

        TODO: implement the endpoint in the node

        @param headers (dict): Optional headers to pass to the request.

        @return Details of the HTTP API provided by the Resdb
        server.
        """
        return self.transport.forward_request(
            method="GET",
            path=self.api_prefix,
            headers=headers,
        )

    def get_transaction(self, txid):
        # TODO
        # use transactions.retieve() instead
        # return self._transactions.retrieve(txid=txid)
        raise NotImplementedError


class NamespacedDriver:
    """! Base class for creating endpoints (namespaced objects) that can be added
    under the :class:`~resdb_driver.driver.Resdb` driver.
    """

    PATH = "/"

    def __init__(self, driver: Resdb):
        """! Initializes an instance of
            :class:`~resdb_driver.driver.NamespacedDriver` with the given
            driver instance.

        @param driver (Resdb): Instance of :class:`~resdb_driver.driver.Resdb`.

        @return An instance of the NamespacedDriver class.
        """
        self.driver = driver

    @property
    def transport(self) -> Transport:
        return self.driver.transport

    @property
    def api_prefix(self) -> str:
        return self.driver.api_prefix

    @property
    def path(self) -> str:
        return self.api_prefix + self.PATH


class TransactionsEndpoint(NamespacedDriver):
    """! Exposes functionality of the ``'/transactions/'`` endpoint.

    Attributes:
        path (str): The path of the endpoint.

    """

    PATH = "/transactions/"

    @staticmethod
    def prepare(
        *,
        operation="CREATE",
        signers=None,
        recipients=None,
        asset=None,
        metadata=None,
        inputs=None
    ) -> dict:
        """! Prepares a transaction payload, ready to be fulfilled.

        @param operation (str): The operation to perform. Must be ``'CREATE'``
                or ``'TRANSFER'``. Case insensitive. Defaults to ``'CREATE'``.
        @param signers (:obj:`list` | :obj:`tuple` | :obj:`str`, optional): One or more public keys representing the issuer(s) of
                the asset being created. Only applies for ``'CREATE'``
                operations. Defaults to ``None``.
        @param recipients (:obj:`list` | :obj:`tuple` | :obj:`str`, optional): One or more public keys representing the new recipients(s)
                of the asset being created or transferred. Defaults to ``None``.
        @param asset (:obj:`list` | :obj:`tuple` | :obj:`str`, optional): The asset to be created or transferred. MUST be supplied
                for ``'TRANSFER'`` operations. Defaults to ``None``.
        @param metadata (:obj:`list` | :obj:`tuple` | :obj:`str`, optional): Metadata associated with the transaction. Defaults to ``None``.
        @param inputs (:obj:`dict` | :obj:`list` | :obj:`tuple`, optional): One or more inputs holding the condition(s) that this
                transaction intends to fulfill. Each input is expected to
                be a :obj:`dict`. Only applies to, and MUST be supplied for,
                ``'TRANSFER'`` operations.

        @return The prepared transaction (dict)

        @exception :class:`~.exceptions.ResdbException`: If ``operation`` is
            not ``'CREATE'`` or ``'TRANSFER'``.

        .. important::

            **CREATE operations**

            * ``signers`` MUST be set.
            * ``recipients``, ``asset``, and ``metadata`` MAY be set.
            * If ``asset`` is set, it MUST be in the form of::

                {
                    'data': {
                        ...
                    }
                }

            * The argument ``inputs`` is ignored.
            * If ``recipients`` is not given, or evaluates to
              ``False``, it will be set equal to ``signers``::

                if not recipients:
                    recipients = signers

            **TRANSFER operations**

            * ``recipients``, ``asset``, and ``inputs`` MUST be set.
            * ``asset`` MUST be in the form of::

                {
                    'id': '<Asset ID (i.e. TX ID of its CREATE transaction)>'
                }

            * ``metadata`` MAY be set.
            * The argument ``signers`` is ignored.

        """
        return prepare_transaction(
            operation=operation,
            signers=signers,
            recipients=recipients,
            asset=asset,
            metadata=metadata,
            inputs=inputs,
        )

    @staticmethod
    def fulfill(
        transaction: dict, private_keys: Union[str, list, tuple]
    ) -> dict[str, Any]:
        """! Fulfills the given transaction.

        @param transaction (dict): The transaction to be fulfilled.
        @param private_keys (:obj:`str` | :obj:`list` | :obj:`tuple`): One or more private keys to be
                used for fulfilling the transaction.

        @return The fulfilled transaction payload, ready to
                be sent to a Resdb federation.

        @exception :exc:`~.exceptions.MissingPrivateKeyError`: If a private
                key is missing.
        """
        return fulfill_transaction(transaction, private_keys=private_keys)

    def get(self, *, asset_id, operation=None, headers=None) -> list:
        """! Given an asset id, get its list of transactions (and
        optionally filter for only ``'CREATE'`` or ``'TRANSFER'``
        transactions).

        Note:
            Please note that the id of an asset in Resdb is
            actually the id of the transaction which created the asset.
            In other words, when querying for an asset id with the
            operation set to ``'CREATE'``, only one transaction should
            be expected. This transaction will be the transaction in
            which the asset was created, and the transaction id will be
            equal to the given asset id. Hence, the following calls to
            :meth:`.retrieve` and :meth:`.get` should return the same
            transaction.

                >>> resdb = Resdb()
                >>> resdb.transactions.retrieve('foo')
                >>> resdb.transactions.get(asset_id='foo', operation='CREATE')

            Since :meth:`.get` returns a list of transactions, it may
            be more efficient to use :meth:`.retrieve` instead, if one
            is only interested in the ``'CREATE'`` operation.

        @param asset_id (str): Id of the asset.
        @param operation (str): The type of operation the transaction
                should be. Either ``'CREATE'`` or ``'TRANSFER'``.
                Defaults to ``None``.
        @param headers (dict): Optional headers to pass to the request.

        @return List of transactions
        """

        return self.transport.forward_request(
            method="GET",
            path=self.path,
            params={"asset_id": asset_id, "operation": operation},
            headers=headers,
        )

    def send_async(self, transaction, headers=None):
        """!
        Note:
            Not used in resdb
        Submit a transaction to the Federation with the mode `async`.

            @param transaction (dict): The transaction to be sent
                to the Federation node(s).
            @param headers (dict): Optional headers to pass to the request.

            @return The transaction sent to the Federation node(s).

        """
        # return self.transport.forward_request(
        #     method="POST",
        #     path=self.path,
        #     json=transaction,
        #     params={"mode": "async"},
        #     headers=headers,
        # )
        raise NotImplementedError

    def send_sync(self, transaction, headers=None):
        """! Note:
        Not used in resdb
        Submit a transaction to the Federation with the mode `sync`.

        @param transaction (dict): The transaction to be sent
            to the Federation node(s).
        @param headers (dict): Optional headers to pass to the request.

        @return The transaction sent to the Federation node(s).

        """
        # return self.transport.forward_request(
        #     method="POST",
        #     path=self.path,
        #     json=transaction,
        #     params={"mode": "sync"},
        #     headers=headers,
        # )
        raise NotImplementedError

    def send_commit(self, transaction: dict, headers: dict = None) -> dict:
        """! Submit a transaction to the Federation with the mode `commit`.

        @param transaction (dict): The transaction to be sent
            to the Federation node(s).
        @param headers (dict): Optional headers to pass to the request.

        @return The transaction sent to the Federation node(s).
        """
        # return self.transport.forward_request(
        #     method='POST',
        #     path=self.path,
        #     json=transaction,
        #     params={'mode': 'commit'},
        #     headers=headers)
        function = "commit"
        path = self.path + function
        return self.transport.forward_request(
            method="POST", path=path, json=transaction, headers=headers
        )

    def retrieve(self, txid: str, headers: dict = None) -> dict:
        """! Retrieves the transaction with the given id.

        @param txid (str): Id of the transaction to retrieve.
        @param headers (dict): Optional headers to pass to the request.

        @return The transaction with the given id.
        """
        path = self.path + txid
        return self.transport.forward_request(method="GET", path=path, headers=None)


class OutputsEndpoint(NamespacedDriver):
    """! TODO:
    add endpoint in nodes
    Exposes functionality of the ``'/outputs'`` endpoint.

    path (str): The path of the endpoint.
    """

    PATH = "/outputs/"

    def get(self, public_key, spent=None, headers=None) -> list[dict]:
        """! Get transaction outputs by public key. The public_key parameter
        must be a base58 encoded ed25519 public key associated with
        transaction output ownership.

        Example:
            Given a transaction with `id` ``da1b64a907ba54`` having an
            `ed25519` condition (at index ``0``) with alice's public
            key::

                >>> resdb = Resdb()
                >>> resdb.outputs.get(alice_pubkey)
                ... ['../transactions/da1b64a907ba54/conditions/0']

        @param public_key (str): Public key for which unfulfilled
            conditions are sought.
        @param spent (bool): Indicate if the result set should include only spent
            or only unspent outputs. If not specified (``None``) the
            result includes all the outputs (both spent and unspent)
            associated with the public key.
        @param headers (dict): Optional headers to pass to the request.

        @return List of unfulfilled conditions.
        """

        return self.transport.forward_request(
            method="GET",
            path=self.path,
            params={"public_key": public_key, "spent": spent},
            headers=headers,
        )


class BlocksEndpoint(NamespacedDriver):
    """! Exposes functionality of the ``'/blocks'`` endpoint.

    Attributes:
        path (str): The path of the endpoint.

    """

    PATH = "/blocks/"

    def get(self, *, txid, headers=None) -> list[dict]:
        """! TODO:
        Add endpoints in nodes. transaction_id is a query parameter here
        Get the block that contains the given transaction id (``txid``)
        else return ``None``

        @param txid (str): Transaction id.
        @param headers (dict): Optional headers to pass to the request.

        @return List of block heights.

        """
        block_list = self.transport.forward_request(
            method="GET",
            path=self.path,
            params={"transaction_id": txid},
            headers=headers,
        )
        return block_list[0] if len(block_list) else None


class AssetsEndpoint(NamespacedDriver):
    """! Exposes functionality of the ``'/assets'`` endpoint.

    path (str): The path of the endpoint.
    """

    PATH = "/assets/"

    def get(self, *, search, limit=0, headers=None) -> list[dict]:
        """! TODO:
        add endpoints in nodes. transaction_id is a query parameter here
        Retrieves the assets that match a given text search string.

        @param search (str): Text search string.
        @param limit (int): Limit the number of returned documents. Defaults to
            zero meaning that it returns all the matching assets.
        @param headers (dict): Optional headers to pass to the request.

        @return List of assets that match the query.
        """

        return self.transport.forward_request(
            method="GET",
            path=self.path,
            params={"search": search, "limit": limit},
            headers=headers,
        )


class MetadataEndpoint(NamespacedDriver):
    """! Exposes functionality of the ``'/metadata'`` endpoint.

    path (str): The path of the endpoint.

    """

    PATH = "/metadata/"

    def get(self, *, search, limit=0, headers=None) -> list[dict]:
        """! Retrieves the metadata that match a given text search string.

        @param search (str): Text search string.
        @param limit (int): Limit the number of returned documents. Defaults to
            zero meaning that it returns all the matching metadata.
        @param headers (dict): Optional headers to pass to the request.

        @return List of metadata that match the query.

        """
        return self.transport.forward_request(
            method="GET",
            path=self.path,
            params={"search": search, "limit": limit},
            headers=headers,
        )
