# -*- coding: utf-8 -*-
"""Copyright 2014-2017 Stephen Rigden

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
from __future__ import annotations

from typing import Any, Dict, Union

import support


class Register:
    """A register of transactions.

    A register object holds the transaction records. There will only be a single instance of
    this class. Each transaction record will link to the 'from' account and either to a pig
    or a second account (the 'to' account).

    Attributes:
        history (dict): The transaction history file. See
        support.RegisterHistoryRecord for the structure.
    """

    def __init__(self) -> None:
        self.history: Dict[str, support.RegisterHistoryRecord] = {}

    @classmethod
    def from_json(cls, **namespace: dict) -> 'Register':
        """Alternative constructor for json loads decoder.

        Args:
            **namespace: Namespace of new register.
        """

        obj = cls()
        obj.__dict__ = namespace
        return obj

    def __str__(self):
        return 'Register with ' + str(len(self)) + ' entry(ies).'

    def __repr__(self):
        return (self.__class__.__qualname__ +
                f"(history={self.history!r})")

    def __eq__(self, other: Union['Register', Any]) -> bool:
        if type(other) is type(self):
            return self.__dict__ == other.__dict__
        return NotImplemented  # pragma: no cover

    def __len__(self) -> int:
        return len(self.history)

    def json_encode(self) -> dict:
        """Create a json serialized string that can recreate self.

        Returns:
            A dictionary with the keys __class__, __id__, __args__,
            and __kw__.
            '__class__' is a tag used to identify this class.
            '__id__' is used to memoize decoded objects.
            '__args__' can be used for positional arguments.
            '__kw__' can be used for keyword arguments.
            The presence of the four keys is used by the json decoder
            to identify the need for a custom handler that will be used to
            recreate this object.
        """

        return dict(__class__='register.Register',
                    __id__=id(self),
                    __args__=[],
                    __kw__=self.__dict__)

    def pig_in_register(self, piggy) -> bool:
        """Is a pig in the register.

        Args:
            piggy: The pig that is to be checked against the register.

        Returns:
            True if the pig is present in the register otherwise False.

        Use Case:
            Deleting a pig which is linked from this register would corrupt the register.
            This method was created to allow any attempt at deletion to check if the pig is
            present and take appropriate action.
        """
        # pigjar-#463 pig_in_register
        for history_rec in self.history.values():
            if id(piggy) == id(history_rec.to_pig_acc):
                return True
        return False
