#!/usr/bin/env python3
from __future__ import annotations

#   Copyright Oli Schacher, Fumail Project
#
# Licensed 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.
#

# Debug suspect filter files

import sys
import os
from fuglu.shared import SuspectFilter, Suspect
import logging
import email


MIN_ARGS = 3


def extract_email(header: str) -> str:
    """
    Try to extract the email address from a header
    """
    start = max(header.find('<') + 1, 0)
    end = header.find('>')
    if end < 0:
        end = len(header)
    return header[start:end].strip()


if __name__ == '__main__':
    if len(sys.argv) < MIN_ARGS:
        print("FuGlu suspect filter debugger")
        print("Usage:")
        print("fuglu_suspectfilter </path/to/filterfile> </path/to/message.eml> [-D]")
        sys.exit(1)

    filterfilename = sys.argv[1]
    messagefilename = sys.argv[2]
    if not os.path.exists(filterfilename):
        print(f"File not found: {filterfilename}")
        sys.exit(1)

    if not os.path.exists(messagefilename):
        print(f"File not found: {messagefilename}")
        sys.exit(1)

    debuglevel = logging.INFO
    if '-D' in sys.argv:
        debuglevel = logging.DEBUG

    logging.basicConfig(level=debuglevel)

    sfilter = SuspectFilter(filterfilename)

    logging.info(f"{len(sfilter.get_list())} valid rules found")

    with open(messagefilename) as fp:
        messagecontent = fp.read()
    if '\r\n\r\n' not in messagecontent and '\n\n' not in messagecontent:
        logging.debug("adding dummy body")
        messagecontent = messagecontent.strip() + "\r\n\r\ndummy body"

    mailmessage = email.message_from_string(messagecontent)

    try:
        sender = extract_email(mailmessage.get('return-path', mailmessage.get('from', 'sender@example.com')))
    except Exception:
        sender = 'sender@example.com'

    try:
        recipient = extract_email(mailmessage.get('delivered-to', mailmessage.get('to', 'recipient@example.com')))
    except Exception:
        recipient = 'recipient@example.com'

    suspect = Suspect(sender, recipient, messagefilename)
    suspect.set_source(messagecontent)

    matchlist = sfilter.get_args(suspect, extended=True)
    matchcount = len(matchlist)
    logging.info(f"{matchcount} matches found")

    for counter, details in enumerate(matchlist, start=1):
        print(f"\nMatch #{counter}:")
        # SuspectFilter.get_args(extended=True) yields SuspectFilterResult objects
        print(f"Matched header/field: {details.fieldname}")
        print(f"Matched value in message: {details.value}")
        print(f"Regex : {details.pattern}")
        print(f"Rule argument : {details.arg}")
