import pytest
from mock import patch

from pre_commit_hooks.detect_aws_credentials import get_aws_credential_files_from_env
from pre_commit_hooks.detect_aws_credentials import get_aws_secrets_from_env
from pre_commit_hooks.detect_aws_credentials import get_aws_secrets_from_file
from pre_commit_hooks.detect_aws_credentials import main
from testing.util import get_resource_path


@pytest.mark.parametrize(
    ('env_vars', 'values'),
    (
        ({}, set()),
        ({'AWS_DUMMY_KEY': '/foo'}, set()),
        ({'AWS_CONFIG_FILE': '/foo'}, {'/foo'}),
        ({'AWS_CREDENTIAL_FILE': '/foo'}, {'/foo'}),
        ({'AWS_SHARED_CREDENTIALS_FILE': '/foo'}, {'/foo'}),
        ({'BOTO_CONFIG': '/foo'}, {'/foo'}),
        ({'AWS_DUMMY_KEY': '/foo', 'AWS_CONFIG_FILE': '/bar'}, {'/bar'}),
        (
            {
                'AWS_DUMMY_KEY': '/foo', 'AWS_CONFIG_FILE': '/bar',
                'AWS_CREDENTIAL_FILE': '/baz',
            },
            {'/bar', '/baz'}
        ),
        (
            {
                'AWS_CONFIG_FILE': '/foo', 'AWS_CREDENTIAL_FILE': '/bar',
                'AWS_SHARED_CREDENTIALS_FILE': '/baz',
            },
            {'/foo', '/bar', '/baz'}
        ),
    ),
)
def test_get_aws_credentials_file_from_env(env_vars, values):
    """Test that reading credential files names from environment variables works."""
    with patch.dict('os.environ', env_vars, clear=True):
        assert get_aws_credential_files_from_env() == values


@pytest.mark.parametrize(
    ('env_vars', 'values'),
    (
        ({}, set()),
        ({'AWS_DUMMY_KEY': 'foo'}, set()),
        ({'AWS_SECRET_ACCESS_KEY': 'foo'}, {'foo'}),
        ({'AWS_SECURITY_TOKEN': 'foo'}, {'foo'}),
        ({'AWS_SESSION_TOKEN': 'foo'}, {'foo'}),
        ({'AWS_DUMMY_KEY': 'foo', 'AWS_SECRET_ACCESS_KEY': 'bar'}, {'bar'}),
        (
            {'AWS_SECRET_ACCESS_KEY': 'foo', 'AWS_SECURITY_TOKEN': 'bar'},
            {'foo', 'bar'},
        ),
    ),
)
def test_get_aws_secrets_from_env(env_vars, values):
    """Test that reading secrets from environment variables works."""
    with patch.dict('os.environ', env_vars, clear=True):
        assert get_aws_secrets_from_env() == values


@pytest.mark.parametrize(
    ('filename', 'expected_keys'),
    (
        (
            'aws_config_with_secret.ini',
            {'z2rpgs5uit782eapz5l1z0y2lurtsyyk6hcfozlb'},
        ),
        ('aws_config_with_session_token.ini', {'foo'}),
        ('aws_config_with_secret_and_session_token.ini',
         {'z2rpgs5uit782eapz5l1z0y2lurtsyyk6hcfozlb', 'foo'}),
        (
            'aws_config_with_multiple_sections.ini',
            {
                '7xebzorgm5143ouge9gvepxb2z70bsb2rtrh099e',
                'z2rpgs5uit782eapz5l1z0y2lurtsyyk6hcfozlb',
                'ixswosj8gz3wuik405jl9k3vdajsnxfhnpui38ez',
                'foo',
            },
        ),
        ('aws_config_without_secrets.ini', set()),
        ('nonsense.txt', set()),
        ('ok_json.json', set()),
    ),
)
def test_get_aws_secrets_from_file(filename, expected_keys):
    """Test that reading secrets from files works."""
    keys = get_aws_secrets_from_file(get_resource_path(filename))
    assert keys == expected_keys


@pytest.mark.parametrize(
    ('filename', 'expected_retval'),
    (
        ('aws_config_with_secret.ini', 1),
        ('aws_config_with_session_token.ini', 1),
        ('aws_config_with_multiple_sections.ini', 1),
        ('aws_config_without_secrets.ini', 0),
        ('nonsense.txt', 0),
        ('ok_json.json', 0),
    ),
)
def test_detect_aws_credentials(filename, expected_retval):
    """Test if getting configured AWS secrets from files to be checked in works."""

    # with a valid credentials file
    ret = main((
        get_resource_path(filename),
        "--credentials-file=testing/resources/aws_config_with_multiple_sections.ini",
    ))
    assert ret == expected_retval


@patch('pre_commit_hooks.detect_aws_credentials.get_aws_secrets_from_file')
@patch('pre_commit_hooks.detect_aws_credentials.get_aws_secrets_from_env')
def test_non_existent_credentials(mock_secrets_env, mock_secrets_file, capsys):
    """Test behavior with no configured AWS secrets."""
    mock_secrets_env.return_value = set()
    mock_secrets_file.return_value = set()
    ret = main((
        get_resource_path('aws_config_without_secrets.ini'),
        "--credentials-file=testing/resources/credentailsfilethatdoesntexist",
    ))
    assert ret == 2
    out, _ = capsys.readouterr()
    assert out == (
        'No AWS keys were found in the configured credential files '
        'and environment variables.\nPlease ensure you have the '
        'correct setting for --credentials-file\n'
    )


@patch('pre_commit_hooks.detect_aws_credentials.get_aws_secrets_from_file')
@patch('pre_commit_hooks.detect_aws_credentials.get_aws_secrets_from_env')
def test_non_existent_credentials_with_allow_flag(mock_secrets_env, mock_secrets_file):
    """Test behavior with no configured AWS secrets and flag to allow when missing."""
    mock_secrets_env.return_value = set()
    mock_secrets_file.return_value = set()
    ret = main((
        get_resource_path('aws_config_without_secrets.ini'),
        "--credentials-file=testing/resources/credentailsfilethatdoesntexist",
        "--allow-missing-credentials",
    ))
    assert ret == 0
