#!/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 os
import time
import datetime
import pytz
import threading
from icalevents.icalevents import events
from flask import Flask, jsonify, abort, request, Response
import prometheus_client as prom

SECRET_ICAL_URL = os.environ.get("SECRET_ICAL_URL")
NO_RESULT_THRESHOLD = 720

app = Flask(__name__)
edges = [
    {
        'name': 'production-edge-example',
        'status': {
            'control_plane': 'connected',
            'user_plane': 'connected'
        },
        'last_update': time.time(),
    }
]

status_codes = {
    "no result": -2,
    "error": -1,
    "disconnected": 0,
    "connecting": 1,
    "connected": 2
}

room_mapping = {
    "production-edge-onf-menlo": "(Compute)-MP-1-Aether Production",
    "production-edge-example": "(Compute)-MP-1-Aether Production" # for testing
}

cp_status = prom.Gauge("aetheredge_status_control_plane", "Control plane status code", ["name"])
up_status = prom.Gauge("aetheredge_status_user_plane", "User plane status code", ["name"])
last_update = prom.Gauge("aetheredge_last_update", "Last reported test result", ["name"])
maint_window = prom.Gauge("aetheredge_in_maintenance_window", "Currently in a maintenance window", ["name"])

def is_my_event(event, name):
    for field in ["summary", "location", "description"]:
        if name in getattr(event, field, ""):
            return True
    return False

def is_naive_datetime(d):
    return d.tzinfo is None or d.tzinfo.utcoffset(d) is None

def process_all_day_events(es):
    for event in es:
        if event.all_day:
            # All day events have naive datetimes, which breaks comparisons
            pacific = pytz.timezone('US/Pacific')
            if is_naive_datetime(event.start):
                event.start = pacific.localize(event.start)
            if is_naive_datetime(event.end):
                event.end = pacific.localize(event.end)

def in_maintenance_window(events, name, now):
    for event in events:
        if event.start < now and event.end > now:
            if is_my_event(event, name):
                return True
            if name in room_mapping and is_my_event(event, room_mapping[name]):
                return True
    return False

def pull_maintenance_events():
    while(True):
        now = datetime.datetime.now(pytz.utc)
        try:
            es  = events(SECRET_ICAL_URL, start = now)
            process_all_day_events(es)
        except Exception as e:
            print(e)
        else:
            for edge in edges:
                if 'maintenance' not in edge:
                    edge['maintenance'] = {}
                edge['maintenance']['in_window'] = in_maintenance_window(es, edge['name'], now)
                edge['maintenance']['last_update'] = time.time()
        time.sleep(60)

def time_out_stale_results():
    for edge in edges:
        time_elapsed = time.time() - edge["last_update"]
        if time_elapsed > NO_RESULT_THRESHOLD:
            edge['status']['control_plane'] = "no result"
            edge['status']['user_plane'] = "no result"


@app.route('/edges/metrics', methods=['GET'])
def get_prometheus_metrics():
    res = []
    time_out_stale_results()
    for edge in edges:
        if edge['name'] == "production-edge-example":
            continue

        cp_status.labels(edge['name']).set(status_codes[edge['status']['control_plane']])
        up_status.labels(edge['name']).set(status_codes[edge['status']['user_plane']])
        last_update.labels(edge['name']).set(edge['last_update'])
        if 'maintenance' in edge:
            maint_window.labels(edge['name']).set(int(edge['maintenance']['in_window']))

    res.append(prom.generate_latest(cp_status))
    res.append(prom.generate_latest(up_status))
    res.append(prom.generate_latest(last_update))
    res.append(prom.generate_latest(maint_window))

    return Response(res, mimetype="text/plain")


@app.route('/edges/healthz', methods=['GET'])
def get_health():
    return {'message': 'healthy'}


@app.route('/edges', methods=['GET'])
def get_edges():
    time_out_stale_results()
    return jsonify({'edges': edges})


@app.route('/edges/<string:name>', methods=['GET'])
def get_edge(name):
    time_out_stale_results()
    edge = [edge for edge in edges if edge['name'] == name]
    if len(edge) == 0:
        abort(404)
    return jsonify({'edge': edge[0]})


@app.route('/edges', methods=['POST'])
def create_or_update_edge():
    if not request.json:
        abort(400)
    if 'name' not in request.json:
        abort(400)
    if 'status' not in request.json:
        abort(400)

    req_edge = {
        'name': request.json['name'],
        'status': {
            'control_plane': request.json['status']['control_plane'],
            'user_plane': request.json['status']['user_plane']
        },
        'last_update': time.time()
    }

    edge = [edge for edge in edges if edge['name'] == req_edge['name']]
    if len(edge) == 0:
        print("new edge request " + req_edge['name'])
        edges.append(req_edge)
    else:
        edge[0]['status']['control_plane'] = req_edge['status']['control_plane']
        edge[0]['status']['user_plane'] = req_edge['status']['user_plane']
        edge[0]['last_update'] = req_edge['last_update']

    return jsonify({'edge': req_edge}), 201


if __name__ == '__main__':
    if SECRET_ICAL_URL:
        print(" * Starting maintenance calendar polling thread")
        t = threading.Thread(target=pull_maintenance_events)
        t.start()
    app.run(debug=True, host='0.0.0.0', port=80)
