"""Unit tests for OpenSourceMalware policy integration."""

import unittest
from metapackage import MetaPackage
from analysis.facts import FactBuilder
from analysis.policy_rules import MalwareRuleEvaluator


class TestOpenSourceMalwarePolicy(unittest.TestCase):
    """Test cases for OpenSourceMalware policy integration."""

    def setUp(self):
        """Set up test fixtures."""
        self.mp = MetaPackage("test-package", "npm")
        self.fact_builder = FactBuilder()

    def test_facts_include_osm(self):
        """Test that facts include OSM fields."""
        self.mp.osm_malicious = True
        self.mp.osm_reason = "Cryptocurrency miner"
        self.mp.osm_threat_count = 1
        self.mp.osm_severity = "critical"

        facts = self.fact_builder.build_facts(self.mp)

        self.assertTrue(facts.get("osm_malicious"))
        self.assertEqual(facts.get("osm_reason"), "Cryptocurrency miner")
        self.assertEqual(facts.get("osm_threat_count"), 1)
        self.assertEqual(facts.get("osm_severity"), "critical")

    def test_malware_rule_evaluator_deny(self):
        """Test that MalwareRuleEvaluator denies malicious packages."""
        evaluator = MalwareRuleEvaluator()
        facts = {
            "package_name": "test-package",
            "osm_malicious": True,
            "osm_reason": "Cryptocurrency miner"
        }
        config = {
            "enabled": True,
            "fail_on_malicious": True
        }

        result = evaluator.evaluate(facts, config)

        self.assertEqual(result["decision"], "deny")
        self.assertGreater(len(result["violated_rules"]), 0)

    def test_malware_rule_evaluator_allow(self):
        """Test that MalwareRuleEvaluator allows clean packages."""
        evaluator = MalwareRuleEvaluator()
        facts = {
            "package_name": "test-package",
            "osm_malicious": False
        }
        config = {
            "enabled": True,
            "fail_on_malicious": True
        }

        result = evaluator.evaluate(facts, config)

        self.assertEqual(result["decision"], "allow")
        self.assertEqual(len(result["violated_rules"]), 0)

    def test_malware_rule_evaluator_disabled(self):
        """Test that MalwareRuleEvaluator allows when disabled."""
        evaluator = MalwareRuleEvaluator()
        facts = {
            "package_name": "test-package",
            "osm_malicious": True
        }
        config = {
            "enabled": False,
            "fail_on_malicious": True
        }

        result = evaluator.evaluate(facts, config)

        self.assertEqual(result["decision"], "allow")
        # When disabled, should not have malicious_but_allowed flag
        self.assertNotIn("osm_malicious_but_allowed", result["evaluated_metrics"])

    def test_malware_rule_evaluator_malicious_but_allowed(self):
        """Test that MalwareRuleEvaluator indicates malicious but allowed in evaluated_metrics."""
        evaluator = MalwareRuleEvaluator()
        facts = {
            "package_name": "test-package",
            "osm_malicious": True,
            "osm_reason": "Cryptocurrency miner"
        }
        config = {
            "enabled": True,
            "fail_on_malicious": False  # Allow malicious packages
        }

        result = evaluator.evaluate(facts, config)

        self.assertEqual(result["decision"], "allow")
        self.assertEqual(len(result["violated_rules"]), 0)
        # Should indicate in evaluated_metrics that malicious was detected but allowed
        self.assertTrue(result["evaluated_metrics"].get("osm_malicious_but_allowed"))
        self.assertIn("package flagged as malicious by OpenSourceMalware",
                     result["evaluated_metrics"].get("osm_malicious_but_allowed_reason", ""))


if __name__ == "__main__":
    unittest.main()
