import os
import re
from webob import Request, Response
from webob import exc
from tempita import HTMLTemplate

VIEW_TEMPLATE = HTMLTemplate(
    """\
<html>
 <head>
  <title>{{page.title}}</title>
 </head>
 <body>
<h1>{{page.title}}</h1>
{{if message}}
<div style="background-color: #99f">{{message}}</div>
{{endif}}

<div>{{page.content|html}}</div>

<hr>
<a href="{{req.url}}?action=edit">Edit</a>
 </body>
</html>
"""
)

EDIT_TEMPLATE = HTMLTemplate(
    """\
<html>
 <head>
  <title>Edit: {{page.title}}</title>
 </head>
 <body>
{{if page.exists}}
<h1>Edit: {{page.title}}</h1>
{{else}}
<h1>Create: {{page.title}}</h1>
{{endif}}

<form action="{{req.path_url}}" method="POST">
 <input type="hidden" name="mtime" value="{{page.mtime}}">
 Title: <input type="text" name="title" style="width: 70%" value="{{page.title}}"><br>
 Content: <input type="submit" value="Save">
 <a href="{{req.path_url}}">Cancel</a>
   <br>
 <textarea name="content" style="width: 100%; height: 75%" rows="40">{{page.content}}</textarea>
   <br>
 <input type="submit" value="Save">
 <a href="{{req.path_url}}">Cancel</a>
</form>
</body></html>
"""
)


class WikiApp:
    view_template = VIEW_TEMPLATE
    edit_template = EDIT_TEMPLATE

    def __init__(self, storage_dir):
        self.storage_dir = os.path.abspath(os.path.normpath(storage_dir))

    def __call__(self, environ, start_response):
        req = Request(environ)
        action = req.params.get("action", "view")
        page = self.get_page(req.path_info)
        try:
            try:
                meth = getattr(self, "action_{}_{}".format(action, req.method))
            except AttributeError:
                raise exc.HTTPBadRequest("No such action %r" % action)
            resp = meth(req, page)
        except exc.HTTPException as e:
            resp = e
        return resp(environ, start_response)

    def get_page(self, path):
        path = path.lstrip("/")
        if not path:
            path = "index"
        path = os.path.join(self.storage_dir, path)
        path = os.path.normpath(path)
        if path.endswith("/"):
            path += "index"
        if not path.startswith(self.storage_dir):
            raise exc.HTTPBadRequest("Bad path")
        path += ".html"
        return Page(path)

    def action_view_GET(self, req, page):
        if not page.exists:
            return exc.HTTPTemporaryRedirect(location=req.url + "?action=edit")
        if req.cookies.get("message"):
            message = req.cookies["message"]
        else:
            message = None
        text = self.view_template.substitute(page=page, req=req, message=message)
        resp = Response(text)
        if message:
            resp.delete_cookie("message")
        else:
            resp.last_modified = page.mtime
            resp.conditional_response = True
        return resp

    def action_view_POST(self, req, page):
        submit_mtime = int(req.params.get("mtime") or "0") or None
        if page.mtime != submit_mtime:
            return exc.HTTPPreconditionFailed(
                "The page has been updated since you started editing it"
            )
        page.set(title=req.params["title"], content=req.params["content"])
        resp = exc.HTTPSeeOther(location=req.path_url)
        resp.set_cookie("message", "Page updated")
        return resp

    def action_edit_GET(self, req, page):
        text = self.edit_template.substitute(page=page, req=req)
        return Response(text)


class Page:
    def __init__(self, filename):
        self.filename = filename

    @property
    def exists(self):
        return os.path.exists(self.filename)

    @property
    def title(self):
        if not self.exists:
            # we need to guess the title
            basename = os.path.splitext(os.path.basename(self.filename))[0]
            basename = re.sub(r"[_-]", " ", basename)
            return basename.capitalize()
        content = self.full_content
        match = re.search(r"<title>(.*?)</title>", content, re.I | re.S)
        return match.group(1)

    @property
    def full_content(self):
        f = open(self.filename, "rb")
        try:
            return f.read()
        finally:
            f.close()

    @property
    def content(self):
        if not self.exists:
            return ""
        content = self.full_content
        match = re.search(r"<body[^>]*>(.*?)</body>", content, re.I | re.S)
        return match.group(1)

    @property
    def mtime(self):
        if not self.exists:
            return None
        else:
            return int(os.stat(self.filename).st_mtime)

    def set(self, title, content):
        dir = os.path.dirname(self.filename)
        if not os.path.exists(dir):
            os.makedirs(dir)
        new_content = (
            """<html><head><title>%s</title></head><body>%s</body></html>"""
            % (title, content)
        )
        f = open(self.filename, "wb")
        f.write(new_content)
        f.close()


if __name__ == "__main__":
    import optparse

    parser = optparse.OptionParser(usage="%prog --port=PORT")
    parser.add_option(
        "-p",
        "--port",
        default="8080",
        dest="port",
        type="int",
        help="Port to serve on (default 8080)",
    )
    parser.add_option(
        "--wiki-data",
        default="./wiki",
        dest="wiki_data",
        help="Place to put wiki data into (default ./wiki/)",
    )
    options, args = parser.parse_args()
    print("Writing wiki pages to %s" % options.wiki_data)
    app = WikiApp(options.wiki_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")
