from __future__ import annotations

import os
from unittest.mock import MagicMock, patch
import pytest

from actions.logs import handle_log_read


def test_invalid_log_type():
    res = handle_log_read({"log_type": "apache_access"})
    assert res["success"] is False
    assert "Invalid log type" in res["error"]


def test_domain_sanitization_and_validation():
    # Sanitization strips invalid characters
    # If domain becomes valid after strip, it should pass
    # E.g. "domain#$.com" becomes "domain.com"
    with patch("os.path.exists", return_value=False):
        res = handle_log_read({"log_type": "nginx_access", "domain": "domain#$.com"})
        assert res["success"] is True
        assert res["lines"] == []

    # If domain is completely invalid and becomes empty, it fails validation
    res = handle_log_read({"log_type": "nginx_access", "domain": "###$$$"})
    assert res["success"] is False
    assert "Invalid domain name format" in res["error"]


@patch("subprocess.run")
def test_nginx_access_tail_called(mock_run):
    mock_run.return_value = MagicMock(returncode=0, stdout="line1\nline2\n", stderr="")
    
    with patch("os.path.exists", return_value=True), patch("os.path.isfile", return_value=True):
        res = handle_log_read({
            "log_type": "nginx_access",
            "domain": "test.com",
            "lines": 10
        })
        
        assert res["success"] is True
        assert res["lines"] == ["line1", "line2"]
        assert res["log_type"] == "nginx_access"
        assert res["path"] == "/var/log/nginx/test.com.access.log"
        
        # Verify subprocess was called with tail -n 10
        mock_run.assert_called_once_with(
            ["tail", "-n", "10", "/var/log/nginx/test.com.access.log"],
            capture_output=True,
            text=True,
            errors="ignore",
            shell=False,
            check=False
        )


@patch("subprocess.run")
def test_system_journalctl_called(mock_run):
    mock_run.return_value = MagicMock(returncode=0, stdout="sys1\nsys2", stderr="")
    
    res = handle_log_read({
        "log_type": "system",
        "lines": 50
    })
    
    assert res["success"] is True
    assert res["lines"] == ["sys1", "sys2"]
    assert res["log_type"] == "system"
    assert res["path"] == "journald"
    
    mock_run.assert_called_once_with(
        ["journalctl", "-n", "50", "--no-pager"],
        capture_output=True,
        text=True,
        errors="ignore",
        shell=False,
        check=False
    )


def test_file_not_found_returns_empty_list():
    with patch("os.path.exists", return_value=False):
        res = handle_log_read({
            "log_type": "nginx_access",
            "domain": "test.com",
            "lines": 10
        })
        assert res["success"] is True
        assert res["lines"] == []
