#   Licensed under the Apache License, Version 2.0 (the "License"); you may
#   not use this file except in compliance with the License. You may obtain
#   a copy of the License at
#
#        http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License 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 copy

from openstackclient.identity.v3 import consumer
from openstackclient.tests import fakes
from openstackclient.tests.identity.v3 import fakes as identity_fakes


class TestOAuth1(identity_fakes.TestOAuth1):

        def setUp(self):
            super(TestOAuth1, self).setUp()
            identity_client = self.app.client_manager.identity
            self.consumers_mock = identity_client.oauth1.consumers
            self.consumers_mock.reset_mock()


class TestConsumerCreate(TestOAuth1):

        def setUp(self):
            super(TestConsumerCreate, self).setUp()

            self.consumers_mock.create.return_value = fakes.FakeResource(
                    None, copy.deepcopy(identity_fakes.OAUTH_CONSUMER),
                    loaded=True)

            self.cmd = consumer.CreateConsumer(self.app, None)

        def test_create_consumer(self):
            arglist = [
                    '--description', identity_fakes.consumer_description
            ]
            verifylist = [
                    ('description', identity_fakes.consumer_description)
            ]
            parsed_args = self.check_parser(self.cmd, arglist, verifylist)
            columns, data = self.cmd.take_action(parsed_args)

            self.consumers_mock.create.assert_called_with(
                identity_fakes.consumer_description)

            collist = ('description', 'id', 'secret')
            self.assertEqual(columns, collist)
            datalist = (
                identity_fakes.consumer_description,
                identity_fakes.consumer_id,
                identity_fakes.consumer_secret
            )
            self.assertEqual(data, datalist)


class TestConsumerDelete(TestOAuth1):

        def setUp(self):
            super(TestConsumerDelete, self).setUp()

            # This is the return value for utils.find_resource()
            self.consumers_mock.get.return_value = fakes.FakeResource(
                None,
                copy.deepcopy(identity_fakes.OAUTH_CONSUMER),
                loaded=True)

            self.consumers_mock.delete.return_value = None
            self.cmd = consumer.DeleteConsumer(self.app, None)

        def test_delete_consumer(self):
            arglist = [
                identity_fakes.consumer_id
            ]
            verifylist = [
                ('consumer', identity_fakes.consumer_id)
            ]
            parsed_args = self.check_parser(self.cmd, arglist, verifylist)

            result = self.cmd.run(parsed_args)
            self.assertEqual(result, 0)

            self.consumers_mock.delete.assert_called_with(
                    identity_fakes.consumer_id,
            )


class TestConsumerList(TestOAuth1):

    def setUp(self):
        super(TestConsumerList, self).setUp()

        self.consumers_mock.get.return_value = fakes.FakeResource(
            None,
            copy.deepcopy(identity_fakes.OAUTH_CONSUMER),
            loaded=True,
        )
        self.consumers_mock.list.return_value = [
            fakes.FakeResource(
                None,
                copy.deepcopy(identity_fakes.OAUTH_CONSUMER),
                loaded=True,
            ),
        ]

        # Get the command object to test
        self.cmd = consumer.ListConsumer(self.app, None)

    def test_consumer_list(self):
        arglist = []
        verifylist = []
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)

        # DisplayCommandBase.take_action() returns two tuples
        columns, data = self.cmd.take_action(parsed_args)
        self.consumers_mock.list.assert_called_with()

        collist = ('ID', 'Description')
        self.assertEqual(columns, collist)
        datalist = ((
            identity_fakes.consumer_id,
            identity_fakes.consumer_description
        ), )
        self.assertEqual(tuple(data), datalist)


class TestConsumerShow(TestOAuth1):

    def setUp(self):
        super(TestConsumerShow, self).setUp()

        consumer_no_secret = copy.deepcopy(identity_fakes.OAUTH_CONSUMER)
        del consumer_no_secret['secret']
        self.consumers_mock.get.return_value = fakes.FakeResource(
            None, consumer_no_secret, loaded=True)

        # Get the command object to test
        self.cmd = consumer.ShowConsumer(self.app, None)

    def test_consumer_show(self):
        arglist = [
            identity_fakes.consumer_id
        ]
        verifylist = [
            ('consumer', identity_fakes.consumer_id)
        ]
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
        columns, data = self.cmd.take_action(parsed_args)

        self.consumers_mock.get.assert_called_with(
            identity_fakes.consumer_id)

        collist = ('description', 'id' )
        self.assertEqual(columns, collist)
        datalist = (
            identity_fakes.consumer_description,
            identity_fakes.consumer_id
        )
        self.assertEqual(data, datalist)


class TestConsumerSet(TestOAuth1):

    def setUp(self):
        super(TestConsumerSet, self).setUp()

        self.consumers_mock.get.return_value = fakes.FakeResource(
            None, copy.deepcopy(identity_fakes.OAUTH_CONSUMER), loaded=True)

        consumer_updated = copy.deepcopy(identity_fakes.OAUTH_CONSUMER)
        consumer_updated['description'] = "consumer new description"
        self.consumers_mock.update.return_value = fakes.FakeResource(
            None, consumer_updated, loaded=True)

        self.cmd = consumer.SetConsumer(self.app, None)

    def test_consumer_update(self):
        new_description = "consumer new description"

        arglist = [
            '--description', new_description,
            identity_fakes.consumer_id
        ]
        verifylist = [
            ('description', new_description),
            ('consumer', identity_fakes.consumer_id)
        ]
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
        result = self.cmd.run(parsed_args)
        self.assertEqual(result, 0)

        kwargs = {'description': new_description}
        self.consumers_mock.update.assert_called_with(
            identity_fakes.consumer_id, **kwargs)
