import re
from collections.abc import Awaitable, Callable, Sequence
from typing import Any, ClassVar

from temporalio import activity, workflow

from csirtmu.beta_temporal.commons.actions import RTCommonActions
from csirtmu.beta_temporal.commons.actions.temporal_common_actions import TemporalCommonActions
from csirtmu.beta_temporal.config import AppConfig
from csirtmu.beta_temporal.constants import WorkflowReference
from csirtmu.beta_temporal.external_services.rt import structs
from csirtmu.beta_temporal.external_services.rt.client import RTClient
from csirtmu.beta_temporal.external_services.rt.utils import get_header
from csirtmu.beta_temporal.workflows.logging import LoggedActivities, LoggedWorkflow


class SetStatusActOnAutomaticCorrespondActivities(LoggedActivities):
    EXCEPTIONS: ClassVar[dict[str, list[str]]] = {
        "qcloud_net_duty@tencent.com": [
            r"^\s*Dear Sir/Madam,\s*Thank you for your email.\s*Please note that this email mailbox is not equipped to handle any infringement reports or government requests."
        ],
        "panel@privatelayer.com": [r"csirt-automatic via RT,\s*Thank you for request. we will be in touch shortly."],
        "abuse+noreply@online.net": [r"^\s*THIS IS AN AUTOMATED MESSAGE - PLEASE DO NOT REPLY DIRECTLY TO THIS EMAIL"],
        "reportabuse@racknerd.com": [
            r"^\s*(RackNerd LLC)?\s*Hello,\s*Thank You for contacting us — we have relayed the abuse complaint details "
            r"over to our end-user at this time, and have provided them with 72 hours to respond to the complaint, in "
            r"addition to a link to our Terms of Service. Feel free to reach back out to us if you still notice this "
            r"being unresolved after a few business days."
        ],
        "abuse@digitalocean.com": [
            r"^\s*-- Please reply above this line --\s*Thank you for your report..*?This mailbox is processed with "
            r"automated tooling due to the high\s*volume of abuse submissions we receive. Our tooling is able to "
            r"parse\s*and accept reports that provide an X-ARF"
        ],
        "security@datapacket.com": [
            r"^\s*Hello,\s*Thank you for submitting your report. It has been forwarded to the respective user of the specified IP address(es) along with an order to cease and desist."
        ],
        "abuse@bredband2.se": [
            r"^Re.*?\s*Vänligen observera att detta är ett automatiskt svar för att bekräfta att ditt ärende har blivit mottaget."
        ],
    }

    def __init__(self, rt_client: RTClient) -> None:
        self.rt_client = rt_client

    def get_activities(self) -> Sequence[Callable[..., Any]]:
        return [self.is_automatic_correspond]

    @activity.defn
    async def is_automatic_correspond(self, transaction: structs.TransactionStruct) -> bool:
        self.log_activity()
        if (
            transaction.type != structs.TransactionTypeEnum.CORRESPOND
            or transaction.ticket_obj is None
            or transaction.ticket_obj.status.lower() not in ["resolved", "closed", "wait"]
            or (transaction.interface is not None and transaction.interface.lower() == "web")
            or (ticket_data := self.rt_client.get_ticket_data(transaction)) is None
        ):
            return False
        for sender in get_header(ticket_data.headers, "From"):
            if re.search(r"ToolGateway", sender, re.IGNORECASE):
                continue
            for key in self.EXCEPTIONS:
                if re.search(re.escape(key), sender, re.IGNORECASE):
                    for reg in self.EXCEPTIONS.get(key, []):
                        if re.search(reg, ticket_data.body, re.IGNORECASE | re.DOTALL):
                            return False
        return True


class SetStatusActOnAutomaticCorrespond(
    LoggedWorkflow, workflow_name=WorkflowReference.SET_STATUS_ACT_ON_AUTOMATIC_CORRESPOND
):
    @classmethod
    def get_activities(cls) -> Sequence[Callable[..., Awaitable[Any]]]:
        config = AppConfig.get()
        rt_client = RTClient(config.rt)
        condition = SetStatusActOnAutomaticCorrespondActivities(rt_client)
        rt_actions = RTCommonActions(rt_client)
        cancel = TemporalCommonActions(config.temporal)
        return [*condition.get_activities(), *rt_actions.get_activities(), *cancel.get_activities()]

    @workflow.run
    async def run(self, transaction: structs.TransactionStruct) -> None:
        self.log_workflow()
        config = AppConfig.get()
        if await workflow.execute_activity(
            SetStatusActOnAutomaticCorrespondActivities.is_automatic_correspond,
            args=(transaction,),
            retry_policy=config.temporal.retry_policy,
            start_to_close_timeout=config.temporal.activity_timeout,
        ):
            await workflow.execute_activity(
                RTCommonActions.set_ticket_status,
                args=("Act", transaction, False),
                retry_policy=config.temporal.retry_policy,
                start_to_close_timeout=config.temporal.activity_timeout,
            )
        elif config.temporal.allow_internal_cancels:
            await workflow.execute_activity(
                TemporalCommonActions.cancel_workflow,
                args=(workflow.info().workflow_id, workflow.info().task_queue),
                retry_policy=config.temporal.retry_policy,
                start_to_close_timeout=config.temporal.activity_timeout,
            )
