# 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
import six

from senlin.common import exception as exc
from senlin.drivers import base as driver_base
from senlin.engine import parser
from senlin.tests.unit.common import base
from senlin.tests.unit.common import utils
from senlin.triggers.ceilometer import alarm

threshold_alarm = """
  type: FakeTriggerType
  version: 1.0
  time_constraints:
    - start: '10 * * * * *'
      duration: 10
  repeat_actions: True
  rule:
    meter_name: cpu_util
    comparison_operator: lt
    threshold: 15
    period: 120
    evaluation_periods: 2
    statistic: avg
    query:
      - field: resource_metadata.cluster
        op: ==
        value: cluster1
"""


combination_alarm = """
  type: FakeTriggerType
  version: 1.0
  rule:
    operator: and
    alarm_ids:
      - alarm_001
      - alarm_002
"""

resource_alarm = """
  type: FakeTriggerType
  version: 1.0
  rule:
    metric: cpu_util
    comparison_operator: gt
    threshold: 75
    granularity: 61
    evaluation_periods: 3
    aggregation_method: avg
    resource_type: instance
    resource_id: 001-002-0003
"""

agg_metric_alarm = """
  type: FakeTriggerType
  version: 1.0
  rule:
    metrics:
      - disk.io.read.bytes
      - disk.io.write.bytes
    comparison_operator: lt
    threshold: 16384
    granularity: 62
    evaluation_periods: 2
    aggregation_method: avg
"""

agg_resource_alarm = """
  type: FakeTriggerType
  version: 1.0
  rule:
    metric: network.read.packets
    comparison_operator: lt
    threshold: 1024
    granularity: 65
    evaluation_periods: 5
    aggregation_method: avg
    resource_type: instance
    query: project_id==1234
"""


class TestCeilometerAlarm(base.SenlinTestCase):

    def setUp(self):
        super(TestCeilometerAlarm, self).setUp()
        self.ctx = utils.dummy_context()

    def test_init(self):
        spec = parser.simple_parse(threshold_alarm)
        a = alarm.Alarm('A1', spec)

        self.assertIsNotNone(a)
        self.assertEqual('FakeTriggerType', a.type_name)
        self.assertEqual('A1', a.name)
        self.assertEqual(spec, a.spec)

        props = a.alarm_properties
        tc = props[alarm.TIME_CONSTRAINTS][0]
        self.assertEqual('10 * * * * *', tc[alarm.TC_START])
        self.assertEqual(10, tc[alarm.TC_DURATION])
        self.assertIsNone(tc[alarm.TC_NAME])
        self.assertEqual('', tc[alarm.TC_TIMEZONE])

        self.assertTrue(props[alarm.REPEAT])

        # For base Alarm, the rule is ignored and set to None
        self.assertIsNone(a.rule)

    def test_validate_illegal_tc_start(self):
        spec = parser.simple_parse(threshold_alarm)
        spec['time_constraints'][0]['start'] = 'XYZ'
        a = alarm.Alarm('A1', spec)

        ex = self.assertRaises(exc.InvalidSpec, a.validate)
        expected = ("Invalid cron expression specified for property 'start' "
                    "(XYZ): Exactly 5 or 6 columns has to be specified for "
                    "iteratorexpression.")
        self.assertEqual(expected, six.text_type(ex))