# Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
#     http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
import os

from awscli.customizations.configure.set import ConfigureSetCommand
from awscli.testutils import mock, unittest

from . import FakeSession


class TestConfigureSetCommand(unittest.TestCase):
    def setUp(self):
        self.session = FakeSession({'config_file': 'myconfigfile'})
        self.fake_credentials_filename = os.path.expanduser(
            '~/fake_credentials_filename'
        )
        self.session.profile = None
        self.config_writer = mock.Mock()

    def test_configure_set_command(self):
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(args=['region', 'us-west-2'], parsed_globals=None)
        self.config_writer.update_config.assert_called_with(
            {'__section__': 'default', 'region': 'us-west-2'},
            'myconfigfile',
            check_permissions=False,
        )

    def test_configure_set_command_dotted(self):
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(args=['plugins.foo', 'true'], parsed_globals=None)
        self.config_writer.update_config.assert_called_with(
            {'__section__': 'plugins', 'foo': 'true'},
            'myconfigfile',
            check_permissions=False,
        )

    def test_configure_set_command_dotted_with_default_profile(self):
        self.session.variables['profile'] = 'default'
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(
            args=['emr.instance_profile', 'my_ip_emr'], parsed_globals=None
        )
        self.config_writer.update_config.assert_called_with(
            {
                '__section__': 'default',
                'emr': {'instance_profile': 'my_ip_emr'},
            },
            'myconfigfile',
            check_permissions=False,
        )

    def test_configure_set_handles_predefined_plugins_section(self):
        self.session.variables['profile'] = 'default'
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(args=['plugins.foo', 'mypackage'], parsed_globals=None)
        self.config_writer.update_config.assert_called_with(
            {'__section__': 'plugins', 'foo': 'mypackage'},
            'myconfigfile',
            check_permissions=False,
        )

    def test_configure_set_command_dotted_with_profile(self):
        self.session.profile = 'emr-dev'
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(
            args=['emr.instance_profile', 'my_ip_emr'], parsed_globals=None
        )
        self.config_writer.update_config.assert_called_with(
            {
                '__section__': 'profile emr-dev',
                'emr': {'instance_profile': 'my_ip_emr'},
            },
            'myconfigfile',
            check_permissions=False,
        )

    def test_configure_set_with_profile(self):
        self.session.profile = 'testing'
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(args=['region', 'us-west-2'], parsed_globals=None)
        self.config_writer.update_config.assert_called_with(
            {'__section__': 'profile testing', 'region': 'us-west-2'},
            'myconfigfile',
            check_permissions=False,
        )

    def test_configure_set_triple_dotted(self):
        # aws configure set default.s3.signature_version s3v4
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(
            args=['default.s3.signature_version', 's3v4'], parsed_globals=None
        )
        self.config_writer.update_config.assert_called_with(
            {'__section__': 'default', 's3': {'signature_version': 's3v4'}},
            'myconfigfile',
            check_permissions=False,
        )

    def test_configure_set_with_profile_nested(self):
        # aws configure set default.s3.signature_version s3v4
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(
            args=['profile.foo.s3.signature_version', 's3v4'],
            parsed_globals=None,
        )
        self.config_writer.update_config.assert_called_with(
            {
                '__section__': 'profile foo',
                's3': {'signature_version': 's3v4'},
            },
            'myconfigfile',
            check_permissions=False,
        )

    def test_access_key_written_to_shared_credentials_file(self):
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(args=['aws_access_key_id', 'foo'], parsed_globals=None)
        self.config_writer.update_config.assert_called_with(
            {'__section__': 'default', 'aws_access_key_id': 'foo'},
            self.fake_credentials_filename,
            check_permissions=True,
        )

    def test_secret_key_written_to_shared_credentials_file(self):
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(args=['aws_secret_access_key', 'foo'], parsed_globals=None)
        self.config_writer.update_config.assert_called_with(
            {'__section__': 'default', 'aws_secret_access_key': 'foo'},
            self.fake_credentials_filename,
            check_permissions=True,
        )

    def test_session_token_written_to_shared_credentials_file(self):
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(args=['aws_session_token', 'foo'], parsed_globals=None)
        self.config_writer.update_config.assert_called_with(
            {'__section__': 'default', 'aws_session_token': 'foo'},
            self.fake_credentials_filename,
            check_permissions=True,
        )

    def test_security_token_written_to_shared_credentials_file(self):
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(args=['aws_security_token', 'foo'], parsed_globals=None)
        self.config_writer.update_config.assert_called_with(
            {'__section__': 'default', 'aws_security_token': 'foo'},
            self.fake_credentials_filename,
            check_permissions=True,
        )

    def test_access_key_written_to_shared_credentials_file_profile(self):
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(
            args=['profile.foo.aws_access_key_id', 'bar'], parsed_globals=None
        )
        self.config_writer.update_config.assert_called_with(
            {'__section__': 'foo', 'aws_access_key_id': 'bar'},
            self.fake_credentials_filename,
            check_permissions=True,
        )

    def test_credential_set_profile_with_space(self):
        self.session.profile = 'some profile'
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(args=['aws_session_token', 'foo'], parsed_globals=None)
        self.config_writer.update_config.assert_called_with(
            {'__section__': 'some profile', 'aws_session_token': 'foo'},
            self.fake_credentials_filename,
            check_permissions=True,
        )

    def test_credential_set_profile_with_space_dotted(self):
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(
            args=['profile.some profile.aws_session_token', 'foo'],
            parsed_globals=None,
        )
        self.config_writer.update_config.assert_called_with(
            {'__section__': 'some profile', 'aws_session_token': 'foo'},
            self.fake_credentials_filename,
            check_permissions=True,
        )

    def test_configure_set_with_profile_with_space(self):
        self.session.profile = 'some profile'
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(args=['region', 'us-west-2'], parsed_globals=None)
        self.config_writer.update_config.assert_called_with(
            {'__section__': "profile 'some profile'", 'region': 'us-west-2'},
            'myconfigfile',
            check_permissions=False,
        )

    def test_configure_set_with_profile_with_space_dotted(self):
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(
            args=['profile.some profile.region', 'us-west-2'],
            parsed_globals=None,
        )
        self.config_writer.update_config.assert_called_with(
            {'__section__': "profile 'some profile'", 'region': 'us-west-2'},
            'myconfigfile',
            check_permissions=False,
        )

    def test_credential_set_profile_with_tab(self):
        self.session.profile = 'some\tprofile'
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(args=['aws_session_token', 'foo'], parsed_globals=None)
        self.config_writer.update_config.assert_called_with(
            {'__section__': 'some\tprofile', 'aws_session_token': 'foo'},
            self.fake_credentials_filename,
            check_permissions=True,
        )

    def test_configure_set_with_profile_with_tab_dotted(self):
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(
            args=['profile.some\tprofile.region', 'us-west-2'],
            parsed_globals=None,
        )
        self.config_writer.update_config.assert_called_with(
            {'__section__': "profile 'some\tprofile'", 'region': 'us-west-2'},
            'myconfigfile',
            check_permissions=False,
        )

    def test_set_top_level_property_in_subsection(self):
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(
            args=['sso_region', 'us-west-2', '--sso-session', 'my-session'],
            parsed_globals=None,
        )
        self.config_writer.update_config.assert_called_with(
            {
                '__section__': 'sso-session my-session',
                'sso_region': 'us-west-2',
            },
            'myconfigfile',
        )

    def test_set_nested_property_in_subsection(self):
        set_command = ConfigureSetCommand(self.session, self.config_writer)
        set_command(
            args=[
                '--services',
                'my-services',
                's3.endpoint_url',
                'http://localhost:4566',
            ],
            parsed_globals=None,
        )
        self.config_writer.update_config.assert_called_with(
            {
                '__section__': 'services my-services',
                's3': {'endpoint_url': 'http://localhost:4566'},
            },
            'myconfigfile',
        )

