from plesk_mail_migrator.utils.hash_utils import HashUtils


class MailMessageUtils(object):
    @classmethod
    def get_normalized_message_id(cls, message_text):
        """Get normalized message ID from message text ("Message-ID" header value)
        for comparison of messages during migration.

        See "How the tool works with message IDs" in README of Windows Mail Migrator for more details.

        :type message_text: str
        :rtype: str
        """
        message_id_marker = 'message-id: '
        for line in message_text.split("\n"):
            line = line.strip("\n\r")
            if line.lower().startswith(message_id_marker) and len(line) > len(message_id_marker):
                # Adding 1 to marker length looks a bit incorrect
                # (it strips the 1st character of the message ID),
                # but necessary for compatibility with Windows Mail Migrator
                # to keep backward compatibility. Also, usually there is nothing
                # bad as the 1st character is usually "<" which is stripped during normalization.
                return cls.normalize_message_id(line[len(message_id_marker) + 1:])

        return HashUtils.calculate_hash(message_text).lower()

    @staticmethod
    def normalize_message_id(message_id):
        """Normalize message ID taken from message headers ("Message-ID" value)
        for comparison of messages during migration.

        See "How the tool works with message IDs" in README for more details.

        :type message_id: str
        :rtype: str
        """
        if message_id is None:
            return None

        message_id = message_id.strip()
        message_id = message_id.strip('><')

        # Use hash of message ID as message ID, to unify algorithm with MailMigrator for Windows,
        # where this is necessary to avoid issues with long file names.
        message_id = HashUtils.calculate_hash(message_id)

        # Make message ID lowercase, so comparison of message IDs works well in case of source
        # case-insensitive filesystem, which is default case when migrating from Windows.
        message_id = message_id.lower()

        return message_id
