# Kemoverse - a gacha-style bot for the Fediverse.
# Copyright © 2025 Waifu, Moon, VD15, and contributors.

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero 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 Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see https://www.gnu.org/licenses/.

import re
import config
from response import generate_response
from fediverse_factory import get_fediverse_service
from fediverse_types import FediverseNotification, NotificationType, Visibility
from custom_types import ParsedNotification

def parse_notification(notification: FediverseNotification, fediverse_service=None):
    '''Parses any notifications received by the bot and sends any commands to
    generate_response()'''
    
    if fediverse_service is None:
        fediverse_service = get_fediverse_service(config.INSTANCE_TYPE)

    # We get the type of notification to filter the ones that we actually want
    # to parse
    if notification.type not in (NotificationType.MENTION, NotificationType.REPLY):
        return  # Ignore anything that isn't a mention

    # Return early if no post attached
    if not notification.post:
        return

    # We want the visibility to be related to the type that was received (so if
    # people don't want to dump a bunch of notes on home they don't have to)
    if notification.post.visibility != Visibility.SPECIFIED:
        visibility = Visibility.HOME
    else:
        visibility = Visibility.SPECIFIED

    # Get the full Activitypub ID of the user
    full_user = notification.user.full_handle

    note_text = notification.post.text
    note_id = notification.post.id

    note = note_text.strip().lower() if note_text else ""
    # Split words into tokens
    parts = note.split()

    # Check for both short and fully-qualified name mentions
    username_variants = [
        config.USER,
        f'@{config.USER.split("@")[1]}'
    ]

    # Notifs must consist of the initial mention and at least one other token
    if len(parts) <= 1:
        return None

    # Make sure the first token is a mention to the bot
    if not parts[0] in username_variants:
        return None

    command = parts[1].lower()
    arguments = parts[2:] if len(parts) > 2 else []

    # Create ParsedNotification object for the new response system
    parsed_notification: ParsedNotification = {
        'author': full_user,
        'command': command,
        'arguments': arguments,
        'note_obj': {
            'id': note_id,
            'text': note_text,
            'files': [{'url': f.url} for f in notification.post.files] if notification.post.files else []
        }
    }

    # Generate response using the new system
    response = generate_response(parsed_notification)
    if not response:
        return

    # Handle attachment URLs (convert to file IDs if needed)
    file_ids = response['attachment_urls'] if response['attachment_urls'] else None

    fediverse_service.create_post(
        text=response['message'],
        reply_to_id=note_id,
        visibility=visibility,
        file_ids=file_ids
        #visible_user_ids=[] #todo: write actual visible users ids so pleromers can use the bot privately
    )
