import os
import urllib2

from flask import Flask, request, json, jsonify
from werkzeug.contrib.cache import FileSystemCache, SimpleCache

app = application = Flask(__name__)

application.config["BOOTCFG_URI"] = os.getenv(
    "BOOTCFG_URI", "http://127.0.0.1:8080")

# application.config["FS_CACHE"] = os.getenv(
#     "FS_CACHE", "/tmp")

# cache = FileSystemCache(application.config["FS_CACHE"])

cache = SimpleCache()

application.config["BOOTCFG_URLS"] = [
    "/",
    "/boot.ipxe",
    "/boot.ipxe.0",
    "/assets"
]


@application.route('/', methods=['GET'])
def root():
    """
    Map the API
    :return: available routes
    """
    links = [k.rule for k in app.url_map.iter_rules()
             if "/static/" != k.rule[:8]]

    return json.jsonify(links)


@application.route('/healthz', methods=['GET'])
def healthz():
    """
    Query all services and return the status
    :return: json
    """
    status = {
        "global": True,
        "flask": True,
        "bootcfg": {
            k: False for k in application.config["BOOTCFG_URLS"]}
    }
    for k in status["bootcfg"]:
        try:
            bootcfg_resp = urllib2.urlopen(
                "%s%s" % (app.config["BOOTCFG_URI"], k))
            assert bootcfg_resp.code == 200
            status["bootcfg"][k] = True
        except Exception:
            status["bootcfg"][k] = False
            status["global"] = False

    return json.jsonify(status)


@application.route('/discovery', methods=['POST'])
def discovery():
    if request.content_type != "application/json":
        try:
            r = json.loads(request.data)
        except ValueError:
            return "Bad Request", 400
    else:
        r = request.get_json()

    interfaces_key = "interfaces"
    if r and interfaces_key in r:

        old_interfaces = cache.get_dict(interfaces_key)[interfaces_key]

        if old_interfaces is None:
            old_interfaces = []

        old_interfaces.append(r[interfaces_key])
        cache.set(key=interfaces_key, value=old_interfaces, timeout=0)
        return jsonify({interfaces_key: len(old_interfaces)})

    return "Bad Request", 400


@application.route('/discovery/interfaces', methods=['GET'])
def discovery_interfaces():
    interfaces_key = "interfaces"
    interfaces = cache.get_dict(interfaces_key)
    return jsonify(interfaces)


@application.route('/boot.ipxe', methods=['GET'])
@application.route('/boot.ipxe.0', methods=['GET'])
def boot_ipxe():
    """
    Replace the bootcfg/boot.ipxe by insert retry for dhcp and full URL for the chain
    :return: str
    """
    try:
        flask_uri = "%s://%s" % (
            request.environ.get('wsgi.url_scheme'),
            request.environ.get('HTTP_HOST'))
    except Exception:
        flask_uri = application.config["BOOTCFG_URI"]

    response = \
        "#!ipxe\n" \
        "echo start /boot.ipxe\n" \
        ":retry_dhcp\n" \
        "dhcp || goto retry_dhcp\n" \
        "chain %s/ipxe?" \
        "uuid=${uuid}&" \
        "mac=${net0/mac:hexhyp}&" \
        "domain=${domain}&" \
        "hostname=${hostname}&" \
        "serial=${serial}\n" % flask_uri
    return response


@application.route('/ipxe', methods=['GET'])
def ipxe():
    """
    Fetch the bootcfg/ipxe?<key>=<value> and insert retry for dhcp
    :return: str
    """
    try:
        bootcfg_resp = urllib2.urlopen(
            "%s%s" % (
                app.config["BOOTCFG_URI"],
                request.full_path))
        resp_list = bootcfg_resp.readlines()
        bootcfg_resp.close()
        # [ipxe, kernel, initrd, boot]
        if len(resp_list) == 4:
            resp_list.insert(1, "echo start /ipxe\n")
            # resp_list.insert(2, ":retry_dhcp\n")
            # resp_list.insert(3, "dhcp || reboot\n")
        else:
            app.logger.warning("iPXE response is not coherent")

        return "".join(resp_list), 200

    except urllib2.URLError:
        return "404", 404


@app.errorhandler(404)
def page_not_found(error):
    return '404\n', 404


if __name__ == "__main__":
    application.run(debug=True)

@@ -1397,16 +1397,52 @@
  False%0A%0A
+    app.logger.debug(%22%25s%22 %25 status)%0A
     retu
@@ -1663,24 +1663,89 @@
 ValueError:%0A
+            app.logger.error(%22ValueError for %25s%22 %25 request.data)%0A
             
@@ -1812,16 +1812,69 @@
 json()%0A%0A
+    app.logger.debug(%22application/json %5C%22%25s%5C%22%22 %25 r)%0A%0A
     inte
@@ -1933,17 +1933,16 @@
 y in r:%0A
-%0A
         
@@ -2257,16 +2257,52 @@
 ces)%7D)%0A%0A
+    app.logger.error(%22Bad Request%22)%0A
     retu
@@ -2908,16 +2908,60 @@
 HOST'))%0A
+        app.logger.debug(%22%25s%22 %25 flask_uri)%0A%0A
     exce
@@ -2964,32 +2964,37 @@
 except Exception
+ as e
 :%0A        flask_
@@ -3032,16 +3032,104 @@
 FG_URI%22%5D
+%0A        app.logger.warning(%22%25s: fall back to BOOTCFG_URI: %25s%22 %25 (e.message, flask_uri))
 %0A%0A    re
@@ -3454,16 +3454,54 @@
 ask_uri%0A
+    app.logger.debug(%22%25s%22 %25 response)%0A
     retu
@@ -4215,20 +4215,24 @@
       re
-turn
+sponse =
  %22%22.join
@@ -4242,16 +4242,82 @@
 sp_list)
+%0A        app.logger.debug(%22%25s%22 %25 response)%0A        return response
 , 200%0A%0A 
@@ -4475,16 +4475,49 @@
 ain__%22:%0A
+    app.logger.setLevel(%22DEBUG%22)%0A
     appl

Debug some message in the API