#!/usr/bin/env python
"""
 Copyright 2017-present Open Networking Laboratory
 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.
"""

from flask import Flask, jsonify, request
import argparse
import json
import sys
import httplib
from httplib import OK, NOT_FOUND, BAD_REQUEST
import jsonschema
from jsonschema import validate


"""
Onos Distributed Manager
this app handles controller information in system

Message Samples :
--Adding node
curl  -H "Content-Type: application/json" -X POST
     --data '{"Id":"1.2.3.4","IpAddress":"1.2.3.4","Port":3456,"IsEnable":true}' http://localhost:5000
--Updating node
curl  -H "Content-Type: application/json" -X PUT --data '{"Id":"1.2.3.4","IpAddress":"1.2.3.4","Port":3456,"IsEnable":true}' http://localhost:5000
--Deleting node
curl  -H "Content-Type: application/json" -X DELETE --data '{"Id":"1.2.3.4","IpAddress":"1.2.3.4","Port":3456,"IsEnable":true}' http://localhost:5000
--Getting node data
curl  -X GET  http://10.15.176.228:5000/cluster.json

"""


schema = {
    "type": "object",
    "properties": {
        "Id": {"type": "string"},
        "Port": {"type": "number"},
        "IsEnable": {"type": "boolean"},
        "IpAddress": {"type": "string"},
    },
    "required": ["Id", "Port", "IsEnable", "IpAddress"]
}


def is_valid_node_json(content):
    try:
        validate(content, schema)
    except Exception as validation_error:
        return False

    return True

class Manager:
    controller_list = {}
    persistence_filename = ""

    def save_to_file(self):
        data = json.dumps(self.controller_list)
        try:
            with open(self.persistence_filename, 'w') as file:
                file.write(data)
                file.close()
        except Exception as error:
            print error
            sys.exit()

    def load_from_file(self):
        try:
            with open(self.persistence_filename, 'r') as file:
                data = file.read()
                self.controller_list = json.loads(data)
        except Exception:
            self.save_to_file()

    def data_get_handler(self):

        pagereturn = "<h2> Onos Distributed Controller Manager2 </h2>"
        pagereturn += "<br><h3> Status of Added controllers  </h3><br>"
        pagereturn += " Id,&emsp; Ip,&emsp; Port,&emsp; Is Active <br> "

        for key in self.controller_list.keys():
            pagereturn += self.controller_list[key]["Id"] + ",&emsp; " + \
                          self.controller_list[key]["IpAddress"] + ",&emsp; " + \
                          str(self.controller_list[key]["Port"]) + ",&emsp; " + \
                          str(self.controller_list[key]["IsEnable"])
            pagereturn += " <br>"

        return pagereturn, OK

    def data_post_handler(self, content):
        if not is_valid_node_json(content):
            return "Id, IpAddress, Port, and IsEnable must be specified", \
                   BAD_REQUEST

        if content["Id"] in self.controller_list:
            return "Content Id is already in the list", BAD_REQUEST

        else:
            self.controller_list[content["Id"]] = content
            self.save_to_file()

        return "POST called with content", OK

    def data_put_handler(self, content):
        if not is_valid_node_json(content):
            return "Id, IpAddress, Port, and IsEnable must be specified", \
                   BAD_REQUEST

        if content["Id"] in self.controller_list:
            self.controller_list[content["Id"]] = content
            self.save_to_file()
            return "Update succeeded", OK

        else:
            return "Id %s is not found " % (content["Id"]), NOT_FOUND

    def data_delete_handler(self, content):
        if content["Id"] in self.controller_list:
            del self.controller_list[content["Id"]]
            self.save_to_file()
            return "Deletion succeed.", OK

        else:
            return "Id is not found", NOT_FOUND

    """
    This function returns onos cluster information
    based on data in memory
    """

    def cluster_responder(self):

        cluster_info = dict()
        nodes = list()
        partition = dict()
        # Todo: For first release , only 1 partition implemented
        cluster_members = list()

        # "nodes" array
        for controller_id in self.controller_list:
            controller_node = self.controller_list[controller_id]
            if controller_node["IsEnable"]:
                node_data = dict()
                node_data["ip"] = controller_node["IpAddress"]
                node_data["id"] = controller_node["Id"]
                node_data["port"] = controller_node["Port"]
                nodes.append(node_data)
                cluster_members.append(controller_node["Id"])

        partition["id"] = 1  # Todo: this will be updated .
        partition["members"] = cluster_members

        cluster_info["nodes"] = nodes
        cluster_info["name"] = -1394421542720337000 # Todo: add a real value here
        cluster_info["partitions"] = partition
        return jsonify(cluster_info), OK

app = Flask(__name__)
manager = Manager()


@app.route('/', methods=['GET'])
def data_get_handler():
    return manager.data_get_handler()


@app.route('/cluster.json', methods=['GET'])
def cluster_responder():
    return manager.cluster_responder()


@app.route('/', methods=['POST'])
def data_post_handler():
    if request.is_json:
        content = dict(request.json)
        return manager.data_post_handler(content)
    else:
        return "json required", BAD_REQUEST


@app.route('/', methods=['PUT'])
def data_put_handler():
    if request.is_json:
        content = dict(request.json)
        return manager.data_put_handler(content)
    else:
        return "json data is missing", BAD_REQUEST


@app.route('/', methods=['DELETE'])
def data_delete_handler():
    if request.is_json:
        content = dict(request.json)
        return manager.data_delete_handler(content)
    else:
        return "No json is found", BAD_REQUEST


def main():
    parser = argparse.ArgumentParser(
        description="Web server and app to maintain ONOS cluster state.")
    parser.add_argument(
        '-p', '--persistence-filename',
        default='./onos-distributed-manager-persistence.json',
        help="Filename used to store persistence information." )

    args = parser.parse_args()
    manager.persistence_filename = args.persistence_filename
    manager.load_from_file()

    app.run(host="0.0.0.0", debug=True)


if __name__ == '__main__':
    manager = Manager()
    main()
