import os
import json
import time

from flask import Flask, render_template, request

from groundstation import logger
log = logger.getLogger(__name__)

# XXX We won't always be using the github adaptor!!
from groundstation.protocols import github as github_protocol
from groundstation.gref import Gref

import pygit2
from groundstation.utils import oid2hex

from groundstation.objects.update_object import UpdateObject

def jsonate(obj, escaped):
    jsonbody = json.dumps(obj)
    if escaped:
        jsonbody = jsonbody.replace("</", "<\\/")
    return jsonbody


def channels_json(station, escaped=False):
    channels = [{"name": channel} for channel in station.channels()]
    return jsonate(channels, escaped)


def grefs_json(station, channel, escaped=False):
    grefs = [gref.as_dict() for gref in station.grefs(channel)]
    return jsonate(grefs, escaped)


def make_airship(station):
    app = Flask(__name__)

    @app.route("/")
    def index():
        return render_template("index.html",
                channels_json=channels_json(station, True),
                current_time=time.time())

    @app.route("/channels")
    def list_channels():
        return channels_json(station)

    @app.route("/grefs/<channel>")
    def list_grefs(channel):
        return grefs_json(station, channel)

    @app.route("/gref/<channel>/<path:identifier>")
    def fetch_gref(channel, identifier):
        adaptor = github_protocol.GithubReadAdaptor(station, channel)
        gref = Gref(station.store, channel, identifier)
        log.info("Trying to fetch channel: %s identifier: %s" %
                (channel, identifier))
        thread = adaptor.get_issue(gref)
        root_obj = thread.pop()
        root = root_obj.as_json()
        root["hash"] = oid2hex(pygit2.hash(root_obj.as_object()))

        response = []

        while thread:
            node = thread.pop()
            data = json.loads(node.data)
            data["parents"] = list(node.parents)
            data["hash"] = oid2hex(pygit2.hash(node.as_object()))
            response.append(data)
        return jsonate({"content": response, "root": root}, False)

    @app.route("/gref/<channel>/<path:identifier>", methods=['POST'])
    def update_gref(channel, identifier):
        # adaptor = github_protocol.GithubWriteAdaptor(station, channel)
        gref = Gref(station.store, channel, identifier)
        # Ugly type coercion
        user = request.form["user"]
        body = request.form["body"]
        parents = map(str, json.loads(request.form["parents"]))
        payload = {
                "type": "comment",
                "id": None,
                "body": body,
                "user": user
                }
        update_object = UpdateObject(parents, json.dumps(payload))
        oid = station.write(update_object.as_object())
        station.update_gref(gref, [oid], parents)
        return jsonate({"response": "ok"}, False)

    return app

@@ -1632,16 +1632,27 @@
         
+marshalled_
 thread =
@@ -1695,22 +1695,42 @@
 t_obj = 
-thread
+marshalled_thread%5B%22roots%22%5D
 .pop()%0A 
@@ -1870,41 +1870,83 @@
 ile 
-thread:%0A            node = thread
+marshalled_thread%5B%22thread%22%5D:%0A            node = marshalled_thread%5B%22thread%22%5D
 .pop
@@ -2134,24 +2134,24 @@
 ppend(data)%0A
-
         retu
@@ -2195,16 +2195,51 @@
 t%22: root
+, %22tips%22: marshalled_thread%5B%22tips%22%5D
 %7D, False

Make marshalling a concern of grefs directly