# -*- encoding: utf-8 -*-
# Copyright (c) 2016 b<>com
#
# 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 functools

from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
from tempest.lib import exceptions

from watcher_tempest_plugin.tests.api.admin import base


class TestCreateDeleteExecuteActionPlan(base.BaseInfraOptimTest):
    """Tests for action plans"""

    @decorators.attr(type='smoke')
    @decorators.idempotent_id('3ac90a92-1022-4868-b93d-ede7ef7b5041')
    def test_create_action_plan(self):
        _, goal = self.client.show_goal("dummy")
        _, audit_template = self.create_audit_template(goal['uuid'])
        _, audit = self.create_audit(audit_template['uuid'])

        self.assertTrue(test_utils.call_until_true(
            func=functools.partial(self.has_audit_finished, audit['uuid']),
            duration=30,
            sleep_for=.5
        ))
        _, action_plans = self.client.list_action_plans(
            audit_uuid=audit['uuid'])
        action_plan = action_plans['action_plans'][0]

        _, action_plan = self.client.show_action_plan(action_plan['uuid'])

        self.assertEqual(audit['uuid'], action_plan['audit_uuid'])
        self.assertEqual('RECOMMENDED', action_plan['state'])

    @decorators.attr(type='smoke')
    @decorators.idempotent_id('621878a9-0a0b-4cf7-952f-6fd5a0cd613e')
    def test_execute_action_plan(self):
        _, goal = self.client.show_goal("dummy")
        _, audit_template = self.create_audit_template(goal['uuid'])

        # Wait for any running action plans to finish before creating audit
        self.wait_for_all_action_plans_to_finish()

        _, audit = self.create_audit(audit_template['uuid'])

        self.assertTrue(test_utils.call_until_true(
            func=functools.partial(self.has_audit_finished, audit['uuid']),
            duration=30,
            sleep_for=.5
        ))

        _, action_plans = self.client.list_action_plans(
            audit_uuid=audit['uuid'])
        action_plan = action_plans['action_plans'][0]

        _, action_plan = self.client.show_action_plan(action_plan['uuid'])
        self.assertEqual('RECOMMENDED', action_plan['state'])

        self.start_action_plan(action_plan['uuid'])

        _, action_plan = self.client.show_action_plan(action_plan['uuid'])
        self.assertEqual('SUCCEEDED', action_plan['state'])

    @decorators.attr(type='smoke')
    @decorators.idempotent_id('67dbb485-5bcb-41d6-b19b-adc8e581eec8')
    def test_delete_action_plan(self):
        _, goal = self.client.show_goal("dummy")
        _, audit_template = self.create_audit_template(goal['uuid'])

        # Wait for any running action plans to finish before creating audit
        self.wait_for_all_action_plans_to_finish()

        _, audit = self.create_audit(audit_template['uuid'])

        self.assertTrue(test_utils.call_until_true(
            func=functools.partial(self.has_audit_finished, audit['uuid']),
            duration=30,
            sleep_for=.5
        ))

        _, action_plans = self.client.list_action_plans(
            audit_uuid=audit['uuid'])
        action_plan = action_plans['action_plans'][0]

        _, action_plan = self.client.show_action_plan(action_plan['uuid'])

        self.client.delete_action_plan(action_plan['uuid'])

        self.assertRaises(exceptions.NotFound, self.client.show_action_plan,
                          action_plan['uuid'])


class TestShowListActionPlan(base.BaseInfraOptimTest):
    """Tests for action_plan."""

    def setUp(self):
        super().setUp()
        _, self.goal = self.client.show_goal("dummy")
        _, self.audit_template = self.create_audit_template(self.goal['uuid'])

        # Wait for any running action plans to finish before creating audit
        self.wait_for_all_action_plans_to_finish()

        _, self.audit = self.create_audit(self.audit_template['uuid'])

        assert test_utils.call_until_true(
            func=functools.partial(
                self.has_audit_finished, self.audit['uuid']),
            duration=30,
            sleep_for=.5
        )

        _, action_plans = self.client.list_action_plans(
            audit_uuid=self.audit['uuid'])
        if len(action_plans['action_plans']) > 0:
            self.action_plan = action_plans['action_plans'][0]

    @decorators.attr(type='smoke')
    @decorators.idempotent_id('33465228-aac1-4688-9db3-6b1532c84323')
    def test_show_action_plan(self):
        _, action_plan = self.client.show_action_plan(
            self.action_plan['uuid'])

        self.assert_expected(self.action_plan, action_plan)

    @decorators.attr(type='smoke')
    @decorators.idempotent_id('fec6938c-215e-41a1-a63b-65000051acdd')
    def test_show_action_plan_detail(self):
        _, action_plans = self.client.list_action_plans_detail(
            audit_uuid=self.audit['uuid'])

        action_plan = action_plans['action_plans'][0]

        self.assert_expected(self.action_plan, action_plan)

    @decorators.attr(type='smoke')
    @decorators.idempotent_id('edf017b4-5685-466d-825d-751ba624e36e')
    def test_show_action_plan_with_links(self):
        _, action_plan = self.client.show_action_plan(
            self.action_plan['uuid'])
        self.assertIn('links', action_plan.keys())
        self.assertEqual(2, len(action_plan['links']))
        self.assertIn(action_plan['uuid'],
                      action_plan['links'][0]['href'])

    @decorators.attr(type="smoke")
    @decorators.idempotent_id('1978e51a-9af2-4d80-a2ba-46caf7fa6f04')
    def test_list_action_plans(self):
        _, body = self.client.list_action_plans()
        self.assertIn(self.action_plan['uuid'],
                      [i['uuid'] for i in body['action_plans']])
        # Verify self links.
        for action_plan in body['action_plans']:
            self.validate_self_link('action_plans', action_plan['uuid'],
                                    action_plan['links'][0]['href'])

    @decorators.attr(type='smoke')
    @decorators.idempotent_id('50e227a7-b173-40fb-8957-82989dba8bca')
    def test_list_with_limit(self):
        # We create 3 extra audits to exceed the limit we fix
        for _ in range(3):
            self.create_action_plan(self.audit_template['uuid'])

        _, body = self.client.list_action_plans(limit=3)

        next_marker = body['action_plans'][-1]['uuid']

        self.assertEqual(3, len(body['action_plans']))
        self.assertIn(next_marker, body['next'])
