#!/usr/bin/env python

# Copyright 2020-present Open Networking Foundation
#
# 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 unittest
import edge_monitoring_server as ems
import datetime
import pytz
import json
import time


test_edge = {
    'name': 'ace-menlo-pixel',
    'status': {
        'control_plane': 'connected',
        'user_plane': 'connected'
    },
    'last_update': time.time()
}


class MyEvent:
    def __init__ (self, location = "", description = "", summary = "", start = None, end = None, all_day = False):
        self.location = location
        self.description = description
        self.summary = summary
        self.start = start
        self.end = end
        self.all_day = all_day

class MyEventNoLoc:
    def __init__ (self, description = "", summary = ""):
        self.description = description
        self.summary = summary


class TestEdgeMonitoringServer(unittest.TestCase):
    def setUp(self):
        self.app = ems.app.test_client()

    def test_match_location(self):
        event = MyEvent(location = "ace-menlo-pixel-production")
        self.assertTrue(ems.is_my_event(event, "ace-menlo-pixel"))
        event = MyEvent(location = "(Compute)-MP-1-Aether Production")
        self.assertTrue(ems.is_my_event(event, "ace-menlo-pixel"))

    def test_match_description(self):
        event = MyEvent(description = "ace-menlo-pixel-production")
        self.assertTrue(ems.is_my_event(event, "ace-menlo-pixel"))
        event = MyEvent(description = "(Compute)-MP-1-Aether Production")
        self.assertTrue(ems.is_my_event(event, "ace-menlo-pixel"))

    def test_match_summary(self):
        event = MyEvent(summary = "ace-menlo-pixel-production")
        self.assertTrue(ems.is_my_event(event, "ace-menlo-pixel"))
        event = MyEvent(summary = "(Compute)-MP-1-Aether Production")
        self.assertTrue(ems.is_my_event(event, "ace-menlo-pixel"))

    def test_no_match(self):
        event = MyEvent(summary = "ace-menlo-pixel-production, (Compute)-MP-1-Aether Production")
        self.assertFalse(ems.is_my_event(event, "ace-intel"))
        self.assertFalse(ems.is_my_event(event, "(Compute)-MP-1-Aether Staging"))
        self.assertFalse(ems.is_my_event(event, "ace-menlo"))

    def test_missing_field(self):
        event = MyEventNoLoc(description = "(Compute)-MP-1-Aether Production")
        self.assertTrue(ems.is_my_event(event, "ace-menlo-pixel"))

    def test_in_window(self):
        events = []
        now = datetime.datetime.now(pytz.utc)
        events.append(MyEvent(location = "(Compute)-MP-1-Aether Production",
            start = now - datetime.timedelta(hours=1),
            end = now + datetime.timedelta(hours=1)))
        self.assertTrue(ems.in_maintenance_window(events, "ace-menlo-pixel", now))
        self.assertFalse(ems.in_maintenance_window(events, "ace-tucson", now))

    def test_not_in_window(self):
        events = []
        now = datetime.datetime.now(pytz.utc)
        events.append(MyEvent(location = "ace-menlo-pixel-production",
            start = now + datetime.timedelta(hours=1),
            end = now + datetime.timedelta(hours=2)))
        self.assertFalse(ems.in_maintenance_window(events, "ace-menlo-pixel", now))

    def test_no_events(self):
        events = []
        now = datetime.datetime.now(pytz.utc)
        self.assertFalse(ems.in_maintenance_window(events, "ace-menlo-pixel", now))

    def test_all_day_events(self):
        events = []
        events.append(MyEvent(location = "ace-menlo-pixel-production",
            start = datetime.datetime(2020, 9, 2, 0, 0),
            end = datetime.datetime(2020, 9, 3, 0, 0),
            all_day = True))

        ems.process_all_day_events(events)

        now = datetime.datetime(2020, 9, 2, 12, 0, tzinfo=pytz.utc)
        self.assertTrue(ems.in_maintenance_window(events, "ace-menlo-pixel", now))

        now = datetime.datetime(2020, 9, 3, 12, 0, tzinfo=pytz.utc)
        self.assertFalse(ems.in_maintenance_window(events, "ace-menlo-pixel", now))

    def test_get_edges(self):
        response = self.app.get('/edges')
        data = json.loads(response.get_data(as_text=True))
        self.assertEqual(len(data['edges']), 1)
        self.assertEqual(data['edges'][0]['name'], 'ace-example')

    def test_create_and_delete_edge(self):
        response = self.app.post('/edges', json=test_edge)
        data = json.loads(response.get_data(as_text=True))
        self.assertEqual(data['edge']['name'], 'ace-menlo-pixel')

        response = self.app.get('/edges')
        data = json.loads(response.get_data(as_text=True))
        self.assertEqual(len(data['edges']), 2)

        response = self.app.get('/edges/metrics')
        data = response.get_data(as_text=True)
        self.assertTrue('aetheredge_status_control_plane{name="ace-menlo-pixel"} 2.0' in data)
        self.assertTrue('aetheredge_status_user_plane{name="ace-menlo-pixel"} 2.0' in data)
        self.assertTrue('aetheredge_last_update{name="ace-menlo-pixel"}' in data)

        response = self.app.delete('/edges/ace-menlo-pixel')
        data = json.loads(response.get_data(as_text=True))
        self.assertEqual(data['result'], True)

        response = self.app.get('/edges/metrics')
        data = response.get_data(as_text=True)
        self.assertFalse('aetheredge_status_control_plane{name="ace-menlo-pixel"} 2.0' in data)
        self.assertFalse('aetheredge_status_user_plane{name="ace-menlo-pixel"} 2.0' in data)
        self.assertFalse('aetheredge_last_update{name="ace-menlo-pixel"}' in data)

        response = self.app.get('/edges')
        data = json.loads(response.get_data(as_text=True))
        self.assertEqual(len(data['edges']), 1)


if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(TestEdgeMonitoringServer)
    unittest.TextTestRunner(verbosity=2).run(suite)
