import unittest
from unittest.mock import patch
from devsecops_engine_tools.engine_sast.engine_secret.src.domain.usecases.secret_scan import (
    SecretScan,
)

class TestSecretScan(unittest.TestCase):
    def setUp(self) -> None:
        global json_config
        json_config = {
            "IGNORE_SEARCH_PATTERN": "(.*test.*)",
            "MESSAGE_INFO_ENGINE_SECRET": "If you have doubts, visit url",
            "THRESHOLD": {
                "VULNERABILITY": {
                    "Critical": 1,
                    "High": 1,
                    "Medium": 1,
                    "Low": 1
                },
                "COMPLIANCE": {
                    "Critical": 0
                }
            },
            "TARGET_BRANCHES": ["trunk", "develop"],
            "trufflehog": {
                "VERSION": "1.2.3",
                "EXCLUDE_PATH": [".git", "node_modules", "target", "build", "build.gradle", "twistcli-scan", ".svg", ".drawio"],
                "NUMBER_THREADS": 4,
                "ENABLE_CUSTOM_RULES" : "True",
                "EXTERNAL_DIR_OWNER": "ExternalOrg",
                "EXTERNAL_DIR_REPOSITORY": "DevSecOps_Checks",
                "APP_ID_GITHUB":"123123",
                "INSTALLATION_ID_GITHUB":"234234",
                "RULES": {
                    "MISSCONFIGURATION_SCANNING" : {
                        "References" : "https://link.reference.com"
                    }
                }
            }
        }

    @patch('devsecops_engine_tools.engine_utilities.git_cli.model.gateway.git_gateway.GitGateway')
    @patch(
        "devsecops_engine_tools.engine_core.src.domain.model.gateway.devops_platform_gateway.DevopsPlatformGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_core.src.domain.model.gateway.devops_platform_gateway.DevopsPlatformGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_sast.engine_secret.src.domain.model.gateway.gateway_deserealizator.DeseralizatorGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_sast.engine_secret.src.domain.model.gateway.tool_gateway.ToolGateway"
    )
    def test_process(
        self, mock_tool_gateway, mock_devops_gateway, mock_remote_config_source, mock_deserialize_gateway, mock_git_gateway
    ):
        # Configuración de mocks
        mock_tool_gateway_instance = mock_tool_gateway.return_value
        mock_devops_gateway_instance = mock_devops_gateway.return_value
        mock_remote_config_source_instance = mock_remote_config_source.return_value
        mock_deserialize_gateway_instance = mock_deserialize_gateway.return_value
        mock_git_gateway_instance = mock_git_gateway.return_value
        mock_dict_args = {
            "remote_config_repo": "example_repo",
            "remote_config_branch": "",
            "folder_path": None,
            "environment": "test",
            "platform": "local",
            "token_external_checks": "fake_github_token",
        }

        secret_tool = "secret"

        secret_scan = SecretScan(
            mock_tool_gateway_instance,
            mock_devops_gateway_instance,
            mock_remote_config_source_instance,
            mock_deserialize_gateway_instance,
            mock_git_gateway_instance
        )

        mock_deserialize_gateway_instance.get_list_vulnerability.return_value = [
            "vulnerability_data"
        ]

        mock_remote_config_source_instance.get_remote_config.return_value = json_config
        mock_devops_gateway_instance.get_variable.return_value = "example_pipeline"
        mock_tool_gateway_instance.run_tool_secret_scan.return_value = (
            "vulnerability_data", "path/findings"
        )

        finding_list, file_path_findings = secret_scan.process(
            False, json_config, secret_tool, mock_dict_args, "trufflehog"
        )

        self.assertEqual(finding_list, ["vulnerability_data"])
        self.assertEqual(file_path_findings, "path/findings")
        mock_tool_gateway_instance.install_tool.assert_called_once()
        mock_tool_gateway_instance.run_tool_secret_scan.assert_called_once()

    @patch('devsecops_engine_tools.engine_utilities.git_cli.model.gateway.git_gateway.GitGateway')
    @patch(
        "devsecops_engine_tools.engine_core.src.domain.model.gateway.devops_platform_gateway.DevopsPlatformGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_core.src.domain.model.gateway.devops_platform_gateway.DevopsPlatformGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_sast.engine_secret.src.domain.model.gateway.gateway_deserealizator.DeseralizatorGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_sast.engine_secret.src.domain.model.gateway.tool_gateway.ToolGateway"
    )
    def test_process_empty(
        self, mock_tool_gateway, mock_devops_gateway, mock_remote_config_source, mock_deserialize_gateway, mock_git_gateway
    ):
        # Configuración de mocks
        mock_tool_gateway_instance = mock_tool_gateway.return_value
        mock_devops_gateway_instance = mock_devops_gateway.return_value
        mock_remote_config_source_instance = mock_remote_config_source.return_value
        mock_deserialize_gateway_instance = mock_deserialize_gateway.return_value
        mock_git_gateway_instance = mock_git_gateway.return_value
        mock_dict_args = {
            "remote_config_repo": "example_repo",
            "remote_config_branch": "",
            "folder_path": ".",
            "environment": "test",
            "platform": "local",
            "token_external_checks": "fake_github_token",
        }

        secret_tool = "secret"

        secret_scan = SecretScan(
            mock_tool_gateway_instance,
            mock_devops_gateway_instance,
            mock_remote_config_source_instance,
            mock_deserialize_gateway_instance,
            mock_git_gateway_instance
        )

        mock_deserialize_gateway_instance.get_list_vulnerability.return_value = []

        mock_remote_config_source_instance.get_remote_config.return_value = json_config
        mock_devops_gateway_instance.get_variable.return_value = "example_pipeline"
        mock_tool_gateway_instance.run_tool_secret_scan.return_value = "", ""

        finding_list, file_path_findings = secret_scan.process(
            False, json_config, secret_tool, mock_dict_args, "trufflehog"
        )

        self.assertEqual(finding_list, [])
        self.assertEqual(file_path_findings, "")
        mock_tool_gateway_instance.install_tool.assert_called_once()
        mock_tool_gateway_instance.run_tool_secret_scan.assert_called_once()

    @patch('devsecops_engine_tools.engine_utilities.git_cli.model.gateway.git_gateway.GitGateway')
    @patch(
        "devsecops_engine_tools.engine_core.src.domain.model.gateway.devops_platform_gateway.DevopsPlatformGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_core.src.domain.model.gateway.devops_platform_gateway.DevopsPlatformGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_sast.engine_secret.src.domain.model.gateway.gateway_deserealizator.DeseralizatorGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_sast.engine_secret.src.domain.model.gateway.tool_gateway.ToolGateway"
    )
    def test_skip_tool_true(self, mock_tool_gateway, mock_devops_gateway, mock_remote_config_source, mock_deserialize_gateway, mock_git_gateway):
        mock_tool_gateway_instance = mock_tool_gateway.return_value
        mock_devops_gateway_instance = mock_devops_gateway.return_value
        mock_remote_config_source_instance = mock_remote_config_source.return_value
        mock_deserialize_gateway_instance = mock_deserialize_gateway.return_value
        mock_git_gateway_instance = mock_git_gateway.return_value
    
        secret_scan = SecretScan(
            mock_tool_gateway_instance,
            mock_devops_gateway_instance,
            mock_remote_config_source_instance,
            mock_deserialize_gateway_instance,
            mock_git_gateway_instance
        )
        skip_tool_isp = False
        mock_devops_gateway_instance = mock_devops_gateway.return_value
        mock_devops_gateway_instance.get_variable.return_value = "test_pipeline"
        exclusions = {
            "test_pipeline": {"SKIP_TOOL": 1}
        }
        result = secret_scan.skip_from_exclusion(exclusions, skip_tool_isp)
        self.assertTrue(result)

    @patch('devsecops_engine_tools.engine_utilities.git_cli.model.gateway.git_gateway.GitGateway')
    @patch(
        "devsecops_engine_tools.engine_core.src.domain.model.gateway.devops_platform_gateway.DevopsPlatformGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_core.src.domain.model.gateway.devops_platform_gateway.DevopsPlatformGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_sast.engine_secret.src.domain.model.gateway.gateway_deserealizator.DeseralizatorGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_sast.engine_secret.src.domain.model.gateway.tool_gateway.ToolGateway"
    )
    def test_skip_tool_true_isp(self, mock_tool_gateway, mock_devops_gateway, mock_remote_config_source, mock_deserialize_gateway, mock_git_gateway):
        mock_tool_gateway_instance = mock_tool_gateway.return_value
        mock_devops_gateway_instance = mock_devops_gateway.return_value
        mock_remote_config_source_instance = mock_remote_config_source.return_value
        mock_deserialize_gateway_instance = mock_deserialize_gateway.return_value
        mock_git_gateway_instance = mock_git_gateway.return_value
    
        secret_scan = SecretScan(
            mock_tool_gateway_instance,
            mock_devops_gateway_instance,
            mock_remote_config_source_instance,
            mock_deserialize_gateway_instance,
            mock_git_gateway_instance
        )
        skip_tool_isp = True
        mock_devops_gateway_instance = mock_devops_gateway.return_value
        mock_devops_gateway_instance.get_variable.return_value = "test_pipeline"
        exclusions = {
            "test_pipeline": {"SKIP_TOOL": 1}
        }
        result = secret_scan.skip_from_exclusion(exclusions, skip_tool_isp)
        self.assertTrue(result)

    @patch('devsecops_engine_tools.engine_utilities.git_cli.model.gateway.git_gateway.GitGateway')
    @patch(
        "devsecops_engine_tools.engine_core.src.domain.model.gateway.devops_platform_gateway.DevopsPlatformGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_core.src.domain.model.gateway.devops_platform_gateway.DevopsPlatformGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_sast.engine_secret.src.domain.model.gateway.gateway_deserealizator.DeseralizatorGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_sast.engine_secret.src.domain.model.gateway.tool_gateway.ToolGateway"
    )
    def test_skip_tool_false(self, mock_tool_gateway, mock_devops_gateway, mock_remote_config_source, mock_deserialize_gateway, mock_git_gateway):
        mock_tool_gateway_instance = mock_tool_gateway.return_value
        mock_devops_gateway_instance = mock_devops_gateway.return_value
        mock_remote_config_source_instance = mock_remote_config_source.return_value
        mock_deserialize_gateway_instance = mock_deserialize_gateway.return_value
        mock_git_gateway_instance = mock_git_gateway.return_value
    
        secret_scan = SecretScan(
            mock_tool_gateway_instance,
            mock_devops_gateway_instance,
            mock_remote_config_source_instance,
            mock_deserialize_gateway_instance,
            mock_git_gateway_instance
        )
        skip_tool_isp = False
        mock_devops_gateway_instance = mock_devops_gateway.return_value
        mock_devops_gateway_instance.get_variable.return_value = "other_pipeline"
        exclusions = {
            "test_pipeline": {"SKIP_TOOL": 1}
        }
        result = secret_scan.skip_from_exclusion(exclusions, skip_tool_isp)
        self.assertFalse(result)
    
    @patch('devsecops_engine_tools.engine_utilities.git_cli.model.gateway.git_gateway.GitGateway')
    @patch(
        "devsecops_engine_tools.engine_core.src.domain.model.gateway.devops_platform_gateway.DevopsPlatformGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_core.src.domain.model.gateway.devops_platform_gateway.DevopsPlatformGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_sast.engine_secret.src.domain.model.gateway.gateway_deserealizator.DeseralizatorGateway"
    )
    @patch(
        "devsecops_engine_tools.engine_sast.engine_secret.src.domain.model.gateway.tool_gateway.ToolGateway"
    )
    def test_complete_config_tool(
        self, mock_tool_gateway, mock_devops_gateway, mock_remote_config_source, mock_deserialize_gateway, mock_git_gateway
    ):
        # Configuración de mocks
        mock_tool_gateway_instance = mock_tool_gateway.return_value
        mock_devops_gateway_instance = mock_devops_gateway.return_value
        mock_remote_config_source_instance = mock_remote_config_source.return_value
        mock_deserialize_gateway_instance = mock_deserialize_gateway.return_value
        mock_git_gateway_instance = mock_git_gateway.return_value

        secret_scan = SecretScan(
            mock_tool_gateway_instance,
            mock_devops_gateway_instance,
            mock_remote_config_source_instance,
            mock_deserialize_gateway_instance,
            mock_git_gateway_instance
        )

        mock_remote_config_source_instance.get_remote_config.return_value = json_config
        mock_devops_gateway_instance.get_variable.return_value = "example_pipeline"

        config_tool_instance, skip_tool_isp = secret_scan.complete_config_tool(
            {"remote_config_repo": "repository", "remote_config_branch": ""}, "TRUFFLEHOG"
        )

        self.assertEqual(config_tool_instance["SCOPE_PIPELINE"], "example_pipeline")

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