from typing import List

from prowler.lib.check.models import Check, CheckReportM365
from prowler.providers.m365.services.defender.defender_client import defender_client


class defender_malware_policy_common_attachments_filter_enabled(Check):
    """
    Check if the Common Attachment Types Filter is enabled in the Defender anti-malware policy.

    Attributes:
        metadata: Metadata associated with the check (inherited from Check).
    """

    def execute(self) -> List[CheckReportM365]:
        """
        Execute the check to verify if the Common Attachment Types Filter is enabled.

        This method checks the Defender anti-malware policies to determine if the
        Common Attachment Types Filter is enabled.

        Returns:
            List[CheckReportM365]: A list of reports containing the result of the check.
        """
        findings = []

        if defender_client.malware_policies:
            # Only Default Defender Malware Policy exists
            if not defender_client.malware_rules:
                policy = defender_client.malware_policies[0]

                report = CheckReportM365(
                    metadata=self.metadata(),
                    resource=policy,
                    resource_name=policy.identity,
                    resource_id=policy.identity,
                )

                if policy.enable_file_filter:
                    # Case 1: Default policy exists and has the setting enabled
                    report.status = "PASS"
                    report.status_extended = f"{policy.identity} is the only policy and Common Attachment Types Filter is enabled."
                else:
                    # Case 5: Default policy exists but doesn't have the setting enabled
                    report.status = "FAIL"
                    report.status_extended = f"{policy.identity} is the only policy and Common Attachment Types Filter is not enabled."
                findings.append(report)

            # Multiple Defender Malware Policies exist
            else:
                default_policy_well_configured = False

                for policy in defender_client.malware_policies:
                    report = CheckReportM365(
                        metadata=self.metadata(),
                        resource=policy,
                        resource_name=policy.identity,
                        resource_id=policy.identity,
                    )

                    if policy.is_default:
                        if not policy.enable_file_filter:
                            # Case 4: Default policy doesn't have the setting enabled and there are other policies
                            report.status = "FAIL"
                            report.status_extended = (
                                f"{policy.identity} is the default policy and Common Attachment Types Filter is not enabled, "
                                "but it could be overridden by another well-configured Custom Policy."
                            )
                            findings.append(report)
                        else:
                            # Case 2: Default policy has the setting enabled and there are other policies
                            report.status = "PASS"
                            report.status_extended = (
                                f"{policy.identity} is the default policy and Common Attachment Types Filter is enabled, "
                                "but it could be overridden by another misconfigured Custom Policy."
                            )
                            default_policy_well_configured = True
                            findings.append(report)
                    else:
                        if not policy.enable_file_filter:
                            included_resources = []

                            if defender_client.malware_rules[policy.identity].users:
                                included_resources.append(
                                    f"users: {', '.join(defender_client.malware_rules[policy.identity].users)}"
                                )
                            if defender_client.malware_rules[policy.identity].groups:
                                included_resources.append(
                                    f"groups: {', '.join(defender_client.malware_rules[policy.identity].groups)}"
                                )
                            if defender_client.malware_rules[policy.identity].domains:
                                included_resources.append(
                                    f"domains: {', '.join(defender_client.malware_rules[policy.identity].domains)}"
                                )

                            included_resources_str = "; ".join(included_resources)

                            if default_policy_well_configured:
                                # Case 3: Default policy enables the setting but custom one doesn't
                                report.status = "FAIL"
                                report.status_extended = (
                                    f"Custom Malware policy {policy.identity} does not enable Common Attachment Types Filter and includes {included_resources_str}, "
                                    f"with priority {defender_client.malware_rules[policy.identity].priority} (0 is the highest). "
                                    "However, the default policy enables the filter, so entities not included by this custom policy could be correctly protected."
                                )
                                findings.append(report)
                            else:
                                # Case 5: Neither default nor custom policies enable the setting
                                report.status = "FAIL"
                                report.status_extended = (
                                    f"Custom Malware policy {policy.identity} does not enable Common Attachment Types Filter and includes {included_resources_str}, "
                                    f"with priority {defender_client.malware_rules[policy.identity].priority} (0 is the highest). "
                                    "Also, the default policy does not enable the filter, so entities not included by this custom policy could not be correctly protected."
                                )
                                findings.append(report)
                        else:
                            included_resources = []

                            if defender_client.malware_rules[policy.identity].users:
                                included_resources.append(
                                    f"users: {', '.join(defender_client.malware_rules[policy.identity].users)}"
                                )
                            if defender_client.malware_rules[policy.identity].groups:
                                included_resources.append(
                                    f"groups: {', '.join(defender_client.malware_rules[policy.identity].groups)}"
                                )
                            if defender_client.malware_rules[policy.identity].domains:
                                included_resources.append(
                                    f"domains: {', '.join(defender_client.malware_rules[policy.identity].domains)}"
                                )

                            included_resources_str = "; ".join(included_resources)

                            if default_policy_well_configured:
                                # Case 2: Both default and custom policies enable the setting
                                report.status = "PASS"
                                report.status_extended = (
                                    f"Custom Malware policy {policy.identity} enables Common Attachment Types Filter and includes {included_resources_str}, "
                                    f"with priority {defender_client.malware_rules[policy.identity].priority} (0 is the highest). "
                                    "Also, the default policy enables the filter, so entities not included by this custom policy could still be correctly protected."
                                )
                                findings.append(report)
                            else:
                                # Case 6: Default policy doesn't enable the setting, but custom policy does
                                report.status = "PASS"
                                report.status_extended = (
                                    f"Custom Malware policy {policy.identity} enables Common Attachment Types Filter and includes {included_resources_str}, "
                                    f"with priority {defender_client.malware_rules[policy.identity].priority} (0 is the highest). "
                                    "However, the default policy does not enable the filter, so entities not included by this custom policy could not be correctly protected."
                                )
                                findings.append(report)

        return findings
