"""
Tests for Config Linter Tool
"""

import pytest
import os
import sys

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from services.router.tool_manager import ToolManager, ToolResult


class TestConfigLinterTool:
    """Test config linter tool functionality"""

    @pytest.mark.asyncio
    async def test_detect_api_key_in_diff(self):
        """Test that API keys in diff are detected as blocking"""
        tool_mgr = ToolManager({})
        
        diff = """diff --git a/config/api.yaml b/config/api.yaml
--- a/config/api.yaml
+++ b/config/api.yaml
@@ -1,3 +1,4 @@
 api:
-  url: https://api.example.com
+  url: https://api.example.com
+  api_key: sk-1234567890abcdefghijklmnop
"""
        
        result = await tool_mgr._config_linter_tool({
            "source": {
                "type": "diff_text",
                "diff_text": diff
            },
            "options": {
                "mask_evidence": True
            }
        })
        
        assert result.success is True
        assert result.result is not None
        assert result.result["stats"]["blocking_count"] > 0
        
        blocking_ids = [f["id"] for f in result.result["blocking"]]
        assert "CFL-003" in blocking_ids or "CFL-006" in blocking_ids

    @pytest.mark.asyncio
    async def test_detect_private_key_blocking(self):
        """Test that private keys are detected as blocking"""
        tool_mgr = ToolManager({})
        
        diff = """diff --git a/keys/service.key b/keys/service.key
--- /dev/null
+++ b/keys/service.key
@@ -0,0 +1,4 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA0Z3VsF3r...
+-----END RSA PRIVATE KEY-----
"""
        
        result = await tool_mgr._config_linter_tool({
            "source": {
                "type": "diff_text",
                "diff_text": diff
            }
        })
        
        assert result.success is True
        blocking_ids = [f["id"] for f in result.result["blocking"]]
        assert "CFL-001" in blocking_ids

    @pytest.mark.asyncio
    async def test_detect_debug_true(self):
        """Test DEBUG=true is detected"""
        tool_mgr = ToolManager({})
        
        diff = """diff --git a/config/app.yml b/config/app.yml
--- a/config/app.yml
+++ b/config/app.yml
@@ -1,2 +1,3 @@
 app:
-  name: myapp
+  name: myapp
+  debug: true
"""
        
        result = await tool_mgr._config_linter_tool({
            "source": {
                "type": "diff_text",
                "diff_text": diff
            }
        })
        
        assert result.success is True
        blocking_ids = [f["id"] for f in result.result["blocking"]]
        assert "CFL-101" in blocking_ids

    @pytest.mark.asyncio
    async def test_detect_cors_wildcard(self):
        """Test CORS wildcard is detected"""
        tool_mgr = ToolManager({})
        
        diff = """diff --git a/config/cors.yaml b/config/cors.yaml
--- a/config/cors.yaml
+++ b/config/cors.yaml
@@ -1,2 +1,3 @@
 cors:
-  allowed_origins:
+  allowed_origins:
+  - "*"
"""
        
        result = await tool_mgr._config_linter_tool({
            "source": {
                "type": "diff_text",
                "diff_text": diff
            }
        })
        
        assert result.success is True
        blocking_ids = [f["id"] for f in result.result["blocking"]]
        assert "CFL-103" in blocking_ids

    @pytest.mark.asyncio
    async def test_detect_auth_bypass(self):
        """Test auth bypass is detected"""
        tool_mgr = ToolManager({})
        
        diff = """diff --git a/config/auth.yaml b/config/auth.yaml
--- a/config/auth.yaml
+++ b/config/auth.yaml
@@ -1,2 +1,3 @@
 auth:
-  enabled: true
+  enabled: true
+  skip_auth: true
"""
        
        result = await tool_mgr._config_linter_tool({
            "source": {
                "type": "diff_text",
                "diff_text": diff
            }
        })
        
        assert result.success is True
        blocking_ids = [f["id"] for f in result.result["blocking"]]
        assert "CFL-104" in blocking_ids

    @pytest.mark.asyncio
    async def test_detect_docker_compose_privileged(self):
        """Test privileged container in docker-compose is detected"""
        tool_mgr = ToolManager({})
        
        diff = """diff --git a/docker-compose.yml b/docker-compose.yml
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,3 +1,5 @@
 services:
   app:
-    image: myapp:latest
+    image: myapp:latest
+    privileged: true
"""
        
        result = await tool_mgr._config_linter_tool({
            "source": {
                "type": "diff_text",
                "diff_text": diff
            }
        })
        
        assert result.success is True
        finding_ids = [f["id"] for f in result.result["blocking"] + result.result["findings"]]
        assert "CFL-302" in finding_ids

    @pytest.mark.asyncio
    async def test_evidence_is_masked(self):
        """Test that evidence is masked when mask_evidence=true"""
        tool_mgr = ToolManager({})
        
        diff = """diff --git a/.env b/.env
--- a/.env
+++ b/.env
@@ -1,2 +1,3 @@
 DATABASE_URL=postgres://localhost
+API_KEY=sk-secret123456789
"""
        
        result = await tool_mgr._config_linter_tool({
            "source": {
                "type": "diff_text",
                "diff_text": diff
            },
            "options": {
                "mask_evidence": True
            }
        })
        
        assert result.success is True
        for finding in result.result["blocking"]:
            assert "sk-s*" in finding["evidence"] or "***" in finding["evidence"]

    @pytest.mark.asyncio
    async def test_path_traversal_blocked(self):
        """Test that path traversal attempts are blocked"""
        tool_mgr = ToolManager({})
        
        result = await tool_mgr._config_linter_tool({
            "source": {
                "type": "paths",
                "paths": ["../../../etc/passwd", "config/app.yml"]
            }
        })
        
        assert result.success is True
        blocking_ids = [f["id"] for f in result.result["blocking"]]
        assert "CFL-999" in blocking_ids

    @pytest.mark.asyncio
    async def test_strict_mode_fails_on_medium(self):
        """Test that strict mode converts medium to blocking"""
        tool_mgr = ToolManager({})
        
        diff = """diff --git a/config/app.yml b/config/app.yml
--- a/config/app.yml
+++ b/config/app.yml
@@ -1,2 +1,3 @@
 app:
-  name: myapp
+  name: myapp
+  allowed_hosts: ["*"]
"""
        
        result = await tool_mgr._config_linter_tool({
            "source": {
                "type": "diff_text",
                "diff_text": diff
            },
            "options": {
                "strict": True
            }
        })
        
        assert result.success is True
        blocking_ids = [f["id"] for f in result.result["blocking"]]
        assert "CFL-106" in blocking_ids

    @pytest.mark.asyncio
    async def test_max_chars_limit(self):
        """Test that max_chars limit is enforced"""
        tool_mgr = ToolManager({})
        
        large_diff = "a" * 500000
        
        result = await tool_mgr._config_linter_tool({
            "source": {
                "type": "diff_text",
                "diff_text": large_diff
            }
        })
        
        assert result.success is False
        assert "max_chars" in result.error.lower()

    @pytest.mark.asyncio
    async def test_clean_diff_no_findings(self):
        """Test that clean diff has no findings"""
        tool_mgr = ToolManager({})
        
        diff = """diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,2 +1,3 @@
 # My Project
+
+New feature added
"""
        
        result = await tool_mgr._config_linter_tool({
            "source": {
                "type": "diff_text",
                "diff_text": diff
            }
        })
        
        assert result.success is True
        assert result.result["stats"]["blocking_count"] == 0

    @pytest.mark.asyncio
    async def test_deterministic_ordering(self):
        """Test that findings are in deterministic order"""
        tool_mgr = ToolManager({})
        
        diff = """diff --git a/config/a.yml b/config/a.yml
--- a/config/a.yml
+++ b/config/a.yml
@@ -1,3 +1,4 @@
+debug: true
+api_key: sk-test123
+password: admin
+auth_disabled: true
"""
        
        result = await tool_mgr._config_linter_tool({
            "source": {
                "type": "diff_text",
                "diff_text": diff
            }
        })
        
        assert result.success is True
        ids = [f["id"] for f in result.result["blocking"]]
        assert ids == sorted(ids)

    @pytest.mark.asyncio
    async def test_github_token_detection(self):
        """Test GitHub token detection"""
        tool_mgr = ToolManager({})
        
        diff = """diff --git a/.env b/.env
--- a/.env
+++ b/.env
@@ -1,2 +1,3 @@
 TOKEN=ghp_1234567890abcdefghijklmnopqrstuvwxyz
"""
        
        result = await tool_mgr._config_linter_tool({
            "source": {
                "type": "diff_text",
                "diff_text": diff
            }
        })
        
        assert result.success is True
        blocking_ids = [f["id"] for f in result.result["blocking"]]
        assert "CFL-007" in blocking_ids

    @pytest.mark.asyncio
    async def test_aws_key_detection(self):
        """Test AWS key detection"""
        tool_mgr = ToolManager({})
        
        diff = """diff --git a/config/aws.yaml b/config/aws.yaml
--- a/config/aws.yaml
+++ b/config/aws.yaml
@@ -1,2 +1,3 @@
 aws:
   access_key: AKIAIOSFODNN7EXAMPLE
"""
        
        result = await tool_mgr._config_linter_tool({
            "source": {
                "type": "diff_text",
                "diff_text": diff
            }
        })
        
        assert result.success is True
        blocking_ids = [f["id"] for f in result.result["blocking"]]
        assert "CFL-009" in blocking_ids

    @pytest.mark.asyncio
    async def test_weak_password_detection(self):
        """Test weak password detection"""
        tool_mgr = ToolManager({})
        
        diff = """diff --git a/config/db.yaml b/config/db.yaml
--- a/config/db.yaml
+++ b/config/db.yaml
@@ -1,2 +1,3 @@
 db:
   password: root
"""
        
        result = await tool_mgr._config_linter_tool({
            "source": {
                "type": "diff_text",
                "diff_text": diff
            }
        })
        
        assert result.success is True
        blocking_ids = [f["id"] for f in result.result["blocking"]]
        assert "CFL-011" in blocking_ids

    @pytest.mark.asyncio
    async def test_container_root_user(self):
        """Test container root user detection"""
        tool_mgr = ToolManager({})
        
        diff = """diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml
--- a/k8s/deployment.yaml
+++ b/k8s/deployment.yaml
@@ -1,3 +1,4 @@
 spec:
   template:
     spec:
+      user: root
"""
        
        result = await tool_mgr._config_linter_tool({
            "source": {
                "type": "diff_text",
                "diff_text": diff
            }
        })
        
        assert result.success is True
        finding_ids = [f["id"] for f in result.result["blocking"] + result.result["findings"]]
        assert "CFL-301" in finding_ids
