#!/usr/bin/env python
#
# 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.
#

from __future__ import print_function
import sys
import threading
from proton.reactor import ApplicationEvent, Container, EventInjector
from proton.handlers import MessagingHandler, TransactionHandler

class TxRecv(MessagingHandler, TransactionHandler):
    def __init__(self):
        super(TxRecv, self).__init__(prefetch=0, auto_accept=False)

    def on_start(self, event):
        self.container = event.container
        self.conn = self.container.connect("localhost:5672")
        self.receiver = self.container.create_receiver(self.conn, "examples")
        self.container.declare_transaction(self.conn, handler=self, settle_before_discharge=True)
        self.transaction = None

    def on_message(self, event):
        print(event.message.body)
        self.transaction.accept(event.delivery)

    def on_transaction_declared(self, event):
        self.transaction = event.transaction
        print("transaction declared")

    def on_transaction_committed(self, event):
        print("transaction committed")
        self.container.declare_transaction(self.conn, handler=self)

    def on_transaction_aborted(self, event):
        print("transaction aborted")
        self.container.declare_transaction(self.conn, handler=self)

    def on_commit(self, event):
        self.transaction.commit()

    def on_abort(self, event):
        self.transaction.abort()

    def on_fetch(self, event):
        self.receiver.flow(1)

    def on_quit(self, event):
        c = self.receiver.connection
        self.receiver.close()
        c.close()

try:
    reactor = Container(TxRecv())
    events = EventInjector()
    reactor.selectable(events)
    thread = threading.Thread(target=reactor.run)
    thread.daemon=True
    thread.start()

    print("Enter 'fetch', 'commit' or 'abort'")
    while True:
        line = sys.stdin.readline()
        if line:
            events.trigger(ApplicationEvent(line.strip()))
        else:
            break
except KeyboardInterrupt: pass


