#!/usr/bin/env python3
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.
#

import tornado.ioloop
import tornado.web
from tornado.gen import coroutine
from tornado.concurrent import Future
from proton import Message
from proton.handlers import MessagingHandler
from proton_tornado import Container


class Client(MessagingHandler):
    def __init__(self, host, address):
        super(Client, self).__init__()
        self.host = host
        self.address = address
        self.sent = []
        self.pending = []
        self.reply_address = None
        self.sender = None
        self.receiver = None

    def on_start(self, event):
        conn = event.container.connect(self.host)
        self.sender = event.container.create_sender(conn, self.address)
        self.receiver = event.container.create_receiver(conn, None, dynamic=True)

    def on_link_opened(self, event):
        if event.receiver == self.receiver:
            self.reply_address = event.link.remote_source.address
            self.do_request()

    def on_sendable(self, event):
        self.do_request()

    def on_message(self, event):
        if self.sent:
            request, future = self.sent.pop(0)
            print("%s => %s" % (request, event.message.body))
            future.set_result(event.message.body)
            self.do_request()

    def do_request(self):
        if self.pending and self.reply_address and self.sender.credit:
            request, future = self.pending.pop(0)
            self.sent.append((request, future))
            req = Message(reply_to=self.reply_address, body=request)
            self.sender.send(req)

    def request(self, body):
        future = Future()
        self.pending.append((body, future))
        self.do_request()
        self.container.touch()
        return future


class ExampleHandler(tornado.web.RequestHandler):
    def initialize(self, client):
        self.client = client

    def get(self):
        self._write_open()
        self._write_form()
        self._write_close()

    @coroutine
    def post(self):
        response = yield self.client.request(self.get_body_argument("message"))
        self.set_header("Content-Type", "text/html")
        self._write_open()
        self._write_form()
        self.write("Response: " + response)
        self._write_close()

    def _write_open(self):
        self.write('<html><body>')

    def _write_close(self):
        self.write('</body></html>')

    def _write_form(self):
        self.write('<form action="/client" method="POST">'
                   'Request: <input type="text" name="message">'
                   '<input type="submit" value="Submit">'
                   '</form>')


loop = tornado.ioloop.IOLoop.instance()
client = Client("localhost:5672", "examples")
client.container = Container(client, loop=loop)
client.container.initialise()
app = tornado.web.Application([tornado.web.url(r"/client", ExampleHandler, dict(client=client))])
app.listen(8888)
try:
    loop.start()
except KeyboardInterrupt:
    loop.stop()
