# -*- coding: utf-8 -*-

""" pySim: tell old 2G SIMs apart from UICC
"""

#
# (C) 2021 by Sysmocom s.f.m.c. GmbH
# All Rights Reserved
#
# 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 2 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 pySim.commands import SimCardCommands
from pySim.filesystem import CardApplication, interpret_sw
from pySim.utils import all_subclasses
import abc
import operator


def _mf_select_test(scc: SimCardCommands, cla_byte: str, sel_ctrl: str) -> bool:
    cla_byte_bak = scc.cla_byte
    sel_ctrl_bak = scc.sel_ctrl
    scc.reset_card()

    scc.cla_byte = cla_byte
    scc.sel_ctrl = sel_ctrl
    rc = True
    try:
        scc.select_file('3f00')
    except:
        rc = False

    scc.reset_card()
    scc.cla_byte = cla_byte_bak
    scc.sel_ctrl = sel_ctrl_bak
    return rc


def match_uicc(scc: SimCardCommands) -> bool:
    """ Try to access MF via UICC APDUs (3GPP TS 102.221), if this works, the
    card is considered a UICC card.
    """
    return _mf_select_test(scc, "00", "0004")


def match_sim(scc: SimCardCommands) -> bool:
    """ Try to access MF via 2G APDUs (3GPP TS 11.11), if this works, the card
    is also a simcard. This will be the case for most UICC cards, but there may
    also be plain UICC cards without 2G support as well.
    """
    return _mf_select_test(scc, "a0", "0000")


class CardProfile(object):
    """A Card Profile describes a card, it's filesystem hierarchy, an [initial] list of
    applications as well as profile-specific SW and shell commands.  Every card has
    one card profile, but there may be multiple applications within that profile."""

    def __init__(self, name, **kw):
        """
        Args:
                desc (str) : Description
                files_in_mf : List of CardEF instances present in MF
                applications : List of CardApplications present on card
                sw : List of status word definitions
                shell_cmdsets : List of cmd2 shell command sets of profile-specific commands
                cla : class byte that should be used with cards of this profile
                sel_ctrl : selection control bytes class byte that should be used with cards of this profile
        """
        self.name = name
        self.desc = kw.get("desc", None)
        self.files_in_mf = kw.get("files_in_mf", [])
        self.sw = kw.get("sw", {})
        self.applications = kw.get("applications", [])
        self.shell_cmdsets = kw.get("shell_cmdsets", [])
        self.cla = kw.get("cla", "00")
        self.sel_ctrl = kw.get("sel_ctrl", "0004")

    def __str__(self):
        return self.name

    def add_application(self, app: CardApplication):
        """Add an application to a card profile.

        Args:
                app : CardApplication instance to be added to profile
        """
        self.applications.append(app)

    def interpret_sw(self, sw: str):
        """Interpret a given status word within the profile.

        Args:
                sw : Status word as string of 4 hex digits

        Returns:
                Tuple of two strings
        """
        return interpret_sw(self.sw, sw)

    @staticmethod
    def decode_select_response(data_hex: str) -> object:
        """Decode the response to a SELECT command.

        This is the fall-back method which doesn't perform any decoding. It mostly
        exists so specific derived classes can overload it for actual decoding.
        This method is implemented in the profile and is only used when application
        specific decoding cannot be performed (no ADF is selected).

        Args:
                data_hex: Hex string of the select response
        """
        return data_hex

    @staticmethod
    @abc.abstractmethod
    def match_with_card(scc: SimCardCommands) -> bool:
        """Check if the specific profile matches the card. This method is a
        placeholder that is overloaded by specific dirived classes. The method
        actively probes the card to make sure the profile class matches the
        physical card. This usually also means that the card is reset during
        the process, so this method must not be called at random times. It may
        only be called on startup.

        Args:
                scc: SimCardCommands class
        Returns:
                match = True, no match = False
        """
        return False

    @staticmethod
    def pick(scc: SimCardCommands):
        profiles = list(all_subclasses(CardProfile))
        profiles.sort(key=operator.attrgetter('ORDER'))

        for p in profiles:
            if p.match_with_card(scc):
                return p()

        return None
