import os
import urllib
import time
import re
from cPickle import load, dump
from webob import Request, Response, html_escape
from webob import exc


class Commenter(object):
    def __init__(self, app, storage_dir):
        self.app = app
        self.storage_dir = storage_dir
        if not os.path.exists(storage_dir):
            os.makedirs(storage_dir)

    def __call__(self, environ, start_response):
        req = Request(environ)
        if req.path_info_peek() == ".comments":
            return self.process_comment(req)(environ, start_response)
        # This is the base path of *this* middleware:
        base_url = req.application_url
        resp = req.get_response(self.app)
        if resp.content_type != "text/html" or resp.status_code != 200:
            # Not an HTML response, we don't want to
            # do anything to it
            return resp(environ, start_response)
        # Make sure the content isn't gzipped:
        resp.decode_content()
        comments = self.get_data(req.url)
        body = resp.body
        body = self.add_to_end(body, self.format_comments(comments))
        body = self.add_to_end(body, self.submit_form(base_url, req))
        resp.body = body
        return resp(environ, start_response)

    def get_data(self, url):
        # Double-quoting makes the filename safe
        filename = self.url_filename(url)
        if not os.path.exists(filename):
            return []
        else:
            f = open(filename, "rb")
            data = load(f)
            f.close()
            return data

    def save_data(self, url, data):
        filename = self.url_filename(url)
        f = open(filename, "wb")
        dump(data, f)
        f.close()

    def url_filename(self, url):
        return os.path.join(self.storage_dir, urllib.quote(url, ""))

    _end_body_re = re.compile(r"</body.*?>", re.I | re.S)

    def add_to_end(self, html, extra_html):
        """
        Adds extra_html to the end of the html page (before </body>)
        """
        match = self._end_body_re.search(html)
        if not match:
            return html + extra_html
        else:
            return html[: match.start()] + extra_html + html[match.start() :]

    def format_comments(self, comments):
        if not comments:
            return ""
        text = []
        text.append("<hr>")
        text.append(
            '<h2><a name="comment-area"></a>Comments (%s):</h2>' % len(comments)
        )
        for comment in comments:
            text.append(
                '<h3><a href="%s">%s</a> at %s:</h3>'
                % (
                    html_escape(comment["homepage"]),
                    html_escape(comment["name"]),
                    time.strftime("%c", comment["time"]),
                )
            )
            # Susceptible to XSS attacks!:
            text.append(comment["comments"])
        return "".join(text)

    def submit_form(self, base_path, req):
        return """<h2>Leave a comment:</h2>
        <form action="%s/.comments" method="POST">
         <input type="hidden" name="url" value="%s">
         <table width="100%%">
          <tr><td>Name:</td>
              <td><input type="text" name="name" style="width: 100%%"></td></tr>
          <tr><td>URL:</td>
              <td><input type="text" name="homepage" style="width: 100%%"></td></tr>
         </table>
         Comments:<br>
         <textarea name="comments" rows=10 style="width: 100%%"></textarea><br>
         <input type="submit" value="Submit comment">
        </form>
        """ % (
            base_path,
            html_escape(req.url),
        )

    def process_comment(self, req):
        try:
            url = req.params["url"]
            name = req.params["name"]
            homepage = req.params["homepage"]
            comments = req.params["comments"]
        except KeyError, e:
            resp = exc.HTTPBadRequest("Missing parameter: %s" % e)
            return resp
        data = self.get_data(url)
        data.append(
            dict(name=name, homepage=homepage, comments=comments, time=time.gmtime())
        )
        self.save_data(url, data)
        resp = exc.HTTPSeeOther(location=url + "#comment-area")
        return resp


if __name__ == "__main__":
    import optparse

    parser = optparse.OptionParser(usage="%prog --port=PORT BASE_DIRECTORY")
    parser.add_option(
        "-p",
        "--port",
        default="8080",
        dest="port",
        type="int",
        help="Port to serve on (default 8080)",
    )
    parser.add_option(
        "--comment-data",
        default="./comments",
        dest="comment_data",
        help="Place to put comment data into (default ./comments/)",
    )
    options, args = parser.parse_args()
    if not args:
        parser.error("You must give a BASE_DIRECTORY")
    base_dir = args[0]
    from paste.urlparser import StaticURLParser

    app = StaticURLParser(base_dir)
    app = Commenter(app, options.comment_data)
    from wsgiref.simple_server import make_server

    httpd = make_server("localhost", options.port, app)
    print("Serving on http://localhost:%s" % options.port)
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        print("^C")
