# 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 mock
from oslo_messaging.rpc import dispatcher as rpc
import six

from senlin.common import consts
from senlin.common import exception as exc
from senlin.engine.actions import base as action_mod
from senlin.engine import dispatcher
from senlin.engine import service
from senlin.objects import cluster as co
from senlin.objects import cluster_policy as cpo
from senlin.objects import policy as po
from senlin.objects.requests import cluster_policies as orcp
from senlin.objects.requests import clusters as orco
from senlin.tests.unit.common import base
from senlin.tests.unit.common import utils


class ClusterPolicyTest(base.SenlinTestCase):

    def setUp(self):
        super(ClusterPolicyTest, self).setUp()
        self.ctx = utils.dummy_context(project='cluster_policy_test_project')
        self.eng = service.EngineService('host-a', 'topic-a')
        self.eng.init_tgm()

    @mock.patch.object(co.Cluster, 'find')
    @mock.patch.object(cpo.ClusterPolicy, 'get_all')
    def test_list2(self, mock_get, mock_find):
        x_obj = mock.Mock(id='FAKE_CLUSTER')
        mock_find.return_value = x_obj
        b1 = mock.Mock()
        b1.to_dict.return_value = {'k': 'v1'}
        b2 = mock.Mock()
        b2.to_dict.return_value = {'k': 'v2'}
        mock_get.return_value = [b1, b2]

        req = orcp.ClusterPolicyListRequest(identity='CLUSTER')
        result = self.eng.cluster_policy_list(
            self.ctx, req.obj_to_primitive())
        self.assertEqual([{'k': 'v1'}, {'k': 'v2'}], result)
        mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
        mock_get.assert_called_once_with(self.ctx, 'FAKE_CLUSTER',
                                         filters={}, sort=None)

    @mock.patch.object(co.Cluster, 'find')
    @mock.patch.object(cpo.ClusterPolicy, 'get_all')
    def test_list2_with_param(self, mock_get, mock_find):
        x_obj = mock.Mock(id='FAKE_CLUSTER')
        mock_find.return_value = x_obj
        mock_get.return_value = []

        params = {
            'identity': 'CLUSTER',
            'policy_name': 'fake_name',
            'policy_type': 'fake_type',
            'enabled': True,
            'sort': 'enabled'
        }

        req = orcp.ClusterPolicyListRequest(**params)

        result = self.eng.cluster_policy_list(
            self.ctx, req.obj_to_primitive())
        self.assertEqual([], result)
        mock_find.assert_called_once_with(self.ctx, 'CLUSTER')

    def test_list2_bad_param(self):
        params = {
            'identity': 'CLUSTER',
            'sort': 'bad',
        }

        ex = self.assertRaises(ValueError,
                               orcp.ClusterPolicyListRequest,
                               **params)
        self.assertEqual("Unsupported sort key 'bad' for 'sort'.",
                         six.text_type(ex))

    @mock.patch.object(co.Cluster, 'find')