#
# 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 org.apache.qpid.proton import Proton
from org.apache.qpid.proton.amqp import Symbol
from org.apache.qpid.proton.amqp.messaging import Source, Target, \
  TerminusDurability, TerminusExpiryPolicy, Received, Accepted, \
  Rejected, Released, Modified
from org.apache.qpid.proton.amqp.transaction import Coordinator
from org.apache.qpid.proton.amqp.transport import ErrorCondition, \
  SenderSettleMode, ReceiverSettleMode
from org.apache.qpid.proton.engine import EndpointState, Sender, \
  Receiver, Transport as _Transport, TransportException, EventType

from java.util import EnumSet
from compat import array, zeros

from cerror import *
from ccodec import *

# from proton/engine.h
PN_LOCAL_UNINIT = 1
PN_LOCAL_ACTIVE = 2
PN_LOCAL_CLOSED = 4
PN_REMOTE_UNINIT = 8
PN_REMOTE_ACTIVE = 16
PN_REMOTE_CLOSED = 32

PN_SND_UNSETTLED = 0
PN_SND_SETTLED = 1
PN_SND_MIXED = 2

PN_RCV_FIRST = 0
PN_RCV_SECOND = 1

PN_UNSPECIFIED = 0
PN_SOURCE = 1
PN_TARGET = 2
PN_COORDINATOR = 3

PN_NONDURABLE = 0
PN_CONFIGURATION = 1
PN_DELIVERIES = 2

PN_EXPIRE_WITH_LINK = 0
PN_EXPIRE_WITH_SESSION = 1
PN_EXPIRE_WITH_CONNECTION = 2
PN_EXPIRE_NEVER = 3

PN_DIST_MODE_UNSPECIFIED = 0
PN_DIST_MODE_COPY = 1
PN_DIST_MODE_MOVE = 2

PN_RECEIVED = (0x0000000000000023)
PN_ACCEPTED = (0x0000000000000024)
PN_REJECTED = (0x0000000000000025)
PN_RELEASED = (0x0000000000000026)
PN_MODIFIED = (0x0000000000000027)

PN_TRACE_OFF = _Transport.TRACE_OFF
PN_TRACE_RAW = _Transport.TRACE_RAW
PN_TRACE_FRM = _Transport.TRACE_FRM
PN_TRACE_DRV = _Transport.TRACE_DRV

def wrap(obj, wrapper):
  if obj:
    ctx = obj.getContext()
    if not ctx:
      ctx = wrapper(obj)
      obj.setContext(ctx)
    return ctx

class pn_condition:

  def __init__(self):
    self.name = None
    self.description = None
    self.info = pn_data(0)

  def decode(self, impl):
    if impl is None:
      self.name = None
      self.description = None
      self.info.clear()
    else:
      cond = impl.getCondition()
      if cond is None:
        self.name = None
      else:
        self.name = cond.toString()
      self.description = impl.getDescription()
      obj2dat(impl.getInfo(), self.info)

  def encode(self):
    if self.name is None:
      return None
    else:
      impl = ErrorCondition()
      impl.setCondition(Symbol.valueOf(self.name))
      impl.setDescription(self.description)
      impl.setInfo(dat2obj(self.info))
      return impl

def pn_condition_is_set(cond):
  return bool(cond.name)

def pn_condition_get_name(cond):
  return cond.name

def pn_condition_set_name(cond, name):
  cond.name = name

def pn_condition_get_description(cond):
  return cond.description

def pn_condition_set_description(cond, description):
  cond.description = description

def pn_condition_clear(cond):
  cond.name = None
  cond.description = None
  cond.info.clear()

def pn_condition_info(cond):
  return cond.info

class endpoint_wrapper:

  def __init__(self, impl):
    self.impl = impl
    self.condition = pn_condition()
    self.remote_condition = pn_condition()

  def on_close(self):
    cond = self.condition.encode()
    if cond:
      self.impl.setCondition(cond)

def remote_condition(self):
  self.remote_condition.decode(self.impl.getRemoteCondition())
  return self.remote_condition

class pn_connection_wrapper(endpoint_wrapper):

  def __init__(self, impl):
    endpoint_wrapper.__init__(self, impl)
    self.properties = pn_data(0)
    self.offered_capabilities = pn_data(0)
    self.desired_capabilities = pn_data(0)

def pn_connection():
  return wrap(Proton.connection(), pn_connection_wrapper)

def set2mask(local, remote):
  mask = 0
  if local.contains(EndpointState.UNINITIALIZED):
    mask |= PN_LOCAL_UNINIT
  if local.contains(EndpointState.ACTIVE):
    mask |= PN_LOCAL_ACTIVE
  if local.contains(EndpointState.CLOSED):
    mask |= PN_LOCAL_CLOSED
  if remote.contains(EndpointState.UNINITIALIZED):
    mask |= PN_REMOTE_UNINIT
  if remote.contains(EndpointState.ACTIVE):
    mask |= PN_REMOTE_ACTIVE
  if remote.contains(EndpointState.CLOSED):
    mask |= PN_REMOTE_CLOSED
  return mask

def endpoint_state(impl):
  return set2mask(EnumSet.of(impl.getLocalState()),
                  EnumSet.of(impl.getRemoteState()))

def pn_connection_state(conn):
  return endpoint_state(conn.impl)

def pn_connection_condition(conn):
  return conn.condition

def pn_connection_remote_condition(conn):
  return remote_condition(conn)

def pn_connection_properties(conn):
  return conn.properties

def pn_connection_remote_properties(conn):
  return obj2dat(conn.impl.getRemoteProperties())

def pn_connection_offered_capabilities(conn):
  return conn.offered_capabilities

def pn_connection_remote_offered_capabilities(conn):
  return array2dat(conn.impl.getRemoteOfferedCapabilities(), PN_SYMBOL)

def pn_connection_desired_capabilities(conn):
  return conn.desired_capabilities

def pn_connection_remote_desired_capabilities(conn):
  return array2dat(conn.impl.getRemoteDesiredCapabilities(), PN_SYMBOL)

def pn_connection_attachments(conn):
  return conn.impl.attachments()

def pn_connection_set_container(conn, name):
  conn.impl.setContainer(name)

def pn_connection_get_container(conn):
  return conn.impl.getContainer()

def pn_connection_remote_container(conn):
  return conn.impl.getRemoteContainer()

def pn_connection_get_hostname(conn):
  return conn.impl.getHostname()

def pn_connection_set_hostname(conn, name):
  conn.impl.setHostname(name)

def pn_connection_remote_hostname(conn):
  return conn.impl.getRemoteHostname()

def pn_connection_open(conn):
  props = dat2obj(conn.properties)
  offered = dat2obj(conn.offered_capabilities)
  desired = dat2obj(conn.desired_capabilities)
  if props:
    conn.impl.setProperties(props)
  if offered:
    conn.impl.setOfferedCapabilities(array(list(offered), Symbol))
  if desired:
    conn.impl.setDesiredCapabilities(array(list(desired), Symbol))
  conn.impl.open()

def pn_connection_close(conn):
  conn.on_close()
  conn.impl.close()

def pn_connection_release(conn):
  conn.impl.free()

def pn_connection_transport(conn):
  return wrap(conn.impl.getTransport(), pn_transport_wrapper)

class pn_session_wrapper(endpoint_wrapper):
  pass

def pn_session(conn):
  return wrap(conn.impl.session(), pn_session_wrapper)

def pn_session_attachments(ssn):
  return ssn.impl.attachments()

def pn_session_state(ssn):
  return endpoint_state(ssn.impl)

def pn_session_get_incoming_capacity(ssn):
  return ssn.impl.getIncomingCapacity()

def pn_session_set_incoming_capacity(ssn, capacity):
  ssn.impl.setIncomingCapacity(capacity)

def pn_session_incoming_bytes(ssn):
  return ssn.impl.getIncomingBytes()

def pn_session_outgoing_bytes(ssn):
  return ssn.impl.getOutgoingBytes()

def pn_session_get_outgoing_window(ssn):
  return ssn.impl.getOutgoingWindow()

def pn_session_set_outgoing_window(ssn, window):
  ssn.impl.setOutgoingWindow(window)

def pn_session_condition(ssn):
  return ssn.condition

def pn_session_remote_condition(ssn):
  return remote_condition(ssn)

def pn_session_open(ssn):
  ssn.impl.open()

def pn_session_close(ssn):
  ssn.on_close()
  ssn.impl.close()

def mask2set(mask):
  local = []
  remote = []
  if PN_LOCAL_UNINIT & mask:
    local.append(EndpointState.UNINITIALIZED)
  if PN_LOCAL_ACTIVE & mask:
    local.append(EndpointState.ACTIVE)
  if PN_LOCAL_CLOSED & mask:
    local.append(EndpointState.CLOSED)
  if PN_REMOTE_UNINIT & mask:
    remote.append(EndpointState.UNINITIALIZED)
  if PN_REMOTE_ACTIVE & mask:
    remote.append(EndpointState.ACTIVE)
  if PN_REMOTE_CLOSED & mask:
    remote.append(EndpointState.CLOSED)

  if local:
    local = EnumSet.of(*local)
  else:
    local = None
  if remote:
    remote = EnumSet.of(*remote)
  else:
    remote = None

  return local, remote

def pn_session_head(conn, mask):
  local, remote = mask2set(mask)
  return wrap(conn.impl.sessionHead(local, remote), pn_session_wrapper)

def pn_session_connection(ssn):
  return wrap(ssn.impl.getConnection(), pn_connection_wrapper)

def pn_sender(ssn, name):
  return wrap(ssn.impl.sender(name), pn_link_wrapper)

def pn_receiver(ssn, name):
  return wrap(ssn.impl.receiver(name), pn_link_wrapper)

def pn_session_free(ssn):
  ssn.impl.free()

TERMINUS_TYPES_J2P = {
  Source: PN_SOURCE,
  Target: PN_TARGET,
  Coordinator: PN_COORDINATOR,
  None.__class__: PN_UNSPECIFIED
}

TERMINUS_TYPES_P2J = {
  PN_SOURCE: Source,
  PN_TARGET: Target,
  PN_COORDINATOR: Coordinator,
  PN_UNSPECIFIED: lambda: None
}

DURABILITY_P2J = {
  PN_NONDURABLE: TerminusDurability.NONE,
  PN_CONFIGURATION: TerminusDurability.CONFIGURATION,
  PN_DELIVERIES: TerminusDurability.UNSETTLED_STATE
}

DURABILITY_J2P = {
  TerminusDurability.NONE: PN_NONDURABLE,
  TerminusDurability.CONFIGURATION: PN_CONFIGURATION,
  TerminusDurability.UNSETTLED_STATE: PN_DELIVERIES
}

EXPIRY_POLICY_P2J = {
  PN_EXPIRE_WITH_LINK: TerminusExpiryPolicy.LINK_DETACH,
  PN_EXPIRE_WITH_SESSION: TerminusExpiryPolicy.SESSION_END,
  PN_EXPIRE_WITH_CONNECTION: TerminusExpiryPolicy.CONNECTION_CLOSE,
  PN_EXPIRE_NEVER: TerminusExpiryPolicy.NEVER
}

EXPIRY_POLICY_J2P = {
  TerminusExpiryPolicy.LINK_DETACH: PN_EXPIRE_WITH_LINK,
  TerminusExpiryPolicy.SESSION_END: PN_EXPIRE_WITH_SESSION,
  TerminusExpiryPolicy.CONNECTION_CLOSE: PN_EXPIRE_WITH_CONNECTION,
  TerminusExpiryPolicy.NEVER: PN_EXPIRE_NEVER
}

DISTRIBUTION_MODE_P2J = {
  PN_DIST_MODE_UNSPECIFIED: None,
  PN_DIST_MODE_COPY: Symbol.valueOf("copy"),
  PN_DIST_MODE_MOVE: Symbol.valueOf("move")
}

DISTRIBUTION_MODE_J2P = {
  None: PN_DIST_MODE_UNSPECIFIED,
  Symbol.valueOf("copy"): PN_DIST_MODE_COPY,
  Symbol.valueOf("move"): PN_DIST_MODE_MOVE
}

class pn_terminus:

  def __init__(self, type):
    self.type = type
    self.address = None
    self.durability = PN_NONDURABLE
    self.expiry_policy = PN_EXPIRE_WITH_SESSION
    self.distribution_mode = PN_DIST_MODE_UNSPECIFIED
    self.timeout = 0
    self.dynamic = False
    self.properties = pn_data(0)
    self.capabilities = pn_data(0)
    self.outcomes = pn_data(0)
    self.filter = pn_data(0)

  def copy(self, src):
    self.type = src.type
    self.address = src.address
    self.durability = src.durability
    self.expiry_policy = src.expiry_policy
    self.timeout = src.timeout
    self.dynamic = src.dynamic
    self.properties = src.properties
    self.capabilities = src.capabilities
    self.outcomes = src.outcomes
    self.filter = src.filter

  def decode(self, impl):
    if impl is not None:
      self.type = TERMINUS_TYPES_J2P[impl.__class__]
      if self.type in (PN_SOURCE, PN_TARGET):
        self.address = impl.getAddress()
        self.durability = DURABILITY_J2P[impl.getDurable()]
        self.expiry_policy = EXPIRY_POLICY_J2P[impl.getExpiryPolicy()]
        self.timeout = impl.getTimeout().longValue()
        self.dynamic = impl.getDynamic()
        obj2dat(impl.getDynamicNodeProperties(), self.properties)
        array2dat(impl.getCapabilities(), PN_SYMBOL, self.capabilities)
        if self.type == PN_SOURCE:
          self.distribution_mode = DISTRIBUTION_MODE_J2P[impl.getDistributionMode()]
          array2dat(impl.getOutcomes(), PN_SYMBOL, self.outcomes)
          obj2dat(impl.getFilter(), self.filter)

  def encode(self):
    impl = TERMINUS_TYPES_P2J[self.type]()
    if self.type in (PN_SOURCE, PN_TARGET):
      impl.setAddress(self.address)
      impl.setDurable(DURABILITY_P2J[self.durability])
      impl.setExpiryPolicy(EXPIRY_POLICY_P2J[self.expiry_policy])
      impl.setTimeout(UnsignedInteger.valueOf(self.timeout))
      impl.setDynamic(self.dynamic)
      props = dat2obj(self.properties)
      caps = dat2obj(self.capabilities)
      if props: impl.setDynamicNodeProperties(props)
      if caps:
        impl.setCapabilities(*array(list(caps), Symbol))
      if self.type == PN_SOURCE:
        impl.setDistributionMode(DISTRIBUTION_MODE_P2J[self.distribution_mode])
        outcomes = dat2obj(self.outcomes)
        filter = dat2obj(self.filter)
        if outcomes: impl.setOutcomes(outcomes)
        if filter: impl.setFilter(filter)
    return impl

def pn_terminus_get_type(terminus):
  return terminus.type

def pn_terminus_set_type(terminus, type):
  terminus.type = type
  return 0

def pn_terminus_get_address(terminus):
  return terminus.address

def pn_terminus_set_address(terminus, address):
  terminus.address = address
  return 0

def pn_terminus_get_durability(terminus):
  return terminus.durability

def pn_terminus_get_expiry_policy(terminus):
  return terminus.expiry_policy

def pn_terminus_set_timeout(terminus, timeout):
  terminus.timeout = timeout
  return 0

def pn_terminus_get_timeout(terminus):
  return terminus.timeout

def pn_terminus_get_distribution_mode(terminus):
  return terminus.distribution_mode

def pn_terminus_set_distribution_mode(terminus, mode):
  terminus.distribution_mode = mode
  return 0

def pn_terminus_is_dynamic(terminus):
  return terminus.dynamic

def pn_terminus_set_dynamic(terminus, dynamic):
  terminus.dynamic = dynamic
  return 0

def pn_terminus_properties(terminus):
  return terminus.properties

def pn_terminus_capabilities(terminus):
  return terminus.capabilities

def pn_terminus_outcomes(terminus):
  return terminus.outcomes

def pn_terminus_filter(terminus):
  return terminus.filter

def pn_terminus_copy(terminus, src):
  terminus.copy(src)
  return 0

class pn_link_wrapper(endpoint_wrapper):

  def __init__(self, impl):
    endpoint_wrapper.__init__(self, impl)
    self.source = pn_terminus(PN_SOURCE)
    self.remote_source = pn_terminus(PN_UNSPECIFIED)
    self.target = pn_terminus(PN_TARGET)
    self.remote_target = pn_terminus(PN_UNSPECIFIED)

  def on_open(self):
    self.impl.setSource(self.source.encode())
    self.impl.setTarget(self.target.encode())

def pn_link_attachments(link):
  return link.impl.attachments()

def pn_link_source(link):
  link.source.decode(link.impl.getSource())
  return link.source

def pn_link_remote_source(link):
  link.remote_source.decode(link.impl.getRemoteSource())
  return link.remote_source

def pn_link_target(link):
  link.target.decode(link.impl.getTarget())
  return link.target

def pn_link_remote_target(link):
  link.remote_target.decode(link.impl.getRemoteTarget())
  return link.remote_target

def pn_link_condition(link):
  return link.condition

def pn_link_remote_condition(link):
  return remote_condition(link)

SND_SETTLE_MODE_P2J = {
  PN_SND_UNSETTLED: SenderSettleMode.UNSETTLED,
  PN_SND_SETTLED: SenderSettleMode.SETTLED,
  PN_SND_MIXED: SenderSettleMode.MIXED,
  None: None
}

SND_SETTLE_MODE_J2P = {
  SenderSettleMode.UNSETTLED: PN_SND_UNSETTLED,
  SenderSettleMode.SETTLED: PN_SND_SETTLED,
  SenderSettleMode.MIXED: PN_SND_MIXED,
  None: None
}

def pn_link_set_snd_settle_mode(link, mode):
  link.impl.setSenderSettleMode(SND_SETTLE_MODE_P2J[mode])

def pn_link_snd_settle_mode(link):
  return SND_SETTLE_MODE_J2P[link.impl.getSenderSettleMode()]

def pn_link_remote_snd_settle_mode(link):
  return SND_SETTLE_MODE_J2P[link.impl.getRemoteSenderSettleMode()]

RCV_SETTLE_MODE_P2J = {
  PN_RCV_FIRST: ReceiverSettleMode.FIRST,
  PN_RCV_SECOND: ReceiverSettleMode.SECOND,
  None: None
}

RCV_SETTLE_MODE_J2P = {
  ReceiverSettleMode.FIRST: PN_RCV_FIRST,
  ReceiverSettleMode.SECOND: PN_RCV_SECOND,
  None: None
}

def pn_link_set_rcv_settle_mode(link, mode):
  link.impl.setReceiverSettleMode(RCV_SETTLE_MODE_P2J[mode])

def pn_link_rcv_settle_mode(link):
  return RCV_SETTLE_MODE_J2P[link.impl.getReceiverSettleMode()]

def pn_link_remote_rcv_settle_mode(link):
  return RCV_SETTLE_MODE_J2P[link.impl.getRemoteReceiverSettleMode()]

def pn_link_is_sender(link):
  return isinstance(link.impl, Sender)

def pn_link_is_receiver(link):
  return isinstance(link.impl, Receiver)

def pn_link_head(conn, mask):
  local, remote = mask2set(mask)
  return wrap(conn.impl.linkHead(local, remote), pn_link_wrapper)

def pn_link_next(link, mask):
  local, remote = mask2set(mask)
  return wrap(link.impl.next(local, remote), pn_link_wrapper)

def pn_link_session(link):
  return wrap(link.impl.getSession(), pn_session_wrapper)

def pn_link_state(link):
  return endpoint_state(link.impl)

def pn_link_name(link):
  return link.impl.getName()

def pn_link_open(link):
  link.on_open()
  link.impl.open()

def pn_link_close(link):
  link.on_close()
  link.impl.close()

def pn_link_detach(link):
  link.on_close()
  link.impl.detach()

def pn_link_flow(link, n):
  link.impl.flow(n)

def pn_link_drain(link, n):
  link.impl.drain(n)

def pn_link_drained(link):
  return link.impl.drained()

def pn_link_draining(link):
  return link.impl.draining()

def pn_link_credit(link):
  return link.impl.getCredit()

def pn_link_queued(link):
  return link.impl.getQueued()

def pn_link_get_drain(link):
  return link.impl.getDrain();

def pn_link_set_drain(link, drain):
  return link.impl.setDrain(drain);

def pn_link_unsettled(link):
  return link.impl.getUnsettled()

def pn_link_send(link, bytes):
  return link.impl.send(array(bytes, 'b'), 0, len(bytes))

def pn_link_recv(link, limit):
  ary = zeros(limit, 'b')
  n = link.impl.recv(ary, 0, limit)
  if n >= 0:
    bytes = ary[:n].tostring()
  else:
    bytes = None
  return n, bytes

def pn_link_advance(link):
  return link.impl.advance()

def pn_link_current(link):
  return wrap(link.impl.current(), pn_delivery_wrapper)

def pn_link_free(link):
  link.impl.free()

def pn_work_head(conn):
  return wrap(conn.impl.getWorkHead(), pn_delivery_wrapper)

def pn_work_next(dlv):
  return wrap(dlv.impl.getWorkNext(), pn_delivery_wrapper)

DELIVERY_STATES = {
  Received: PN_RECEIVED,
  Accepted: PN_ACCEPTED,
  Rejected: PN_REJECTED,
  Released: PN_RELEASED,
  Modified: PN_MODIFIED,
  None.__class__: 0
  }

DISPOSITIONS = {
  PN_RECEIVED: Received,
  PN_ACCEPTED: Accepted,
  PN_REJECTED: Rejected,
  PN_RELEASED: Released,
  PN_MODIFIED: Modified,
  0: lambda: None
}

class pn_disposition:

  def __init__(self):
    self.type = 0
    self.data = pn_data(0)
    self.failed = False
    self.undeliverable = False
    self.annotations = pn_data(0)
    self.condition = pn_condition()
    self.section_number = 0
    self.section_offset = 0

  def decode(self, impl):
    self.type = DELIVERY_STATES[impl.__class__]

    if self.type == PN_REJECTED:
      self.condition.decode(impl.getError())
    else:
      pn_condition_clear(self.condition)

    if self.type == PN_MODIFIED:
      self.failed = impl.getDeliveryFailed()
      self.undeliverable = impl.getUndeliverableHere()
      obj2dat(impl.getMessageAnnotations(), self.annotations)
    else:
      self.failed = False
      self.undeliverable = False
      pn_data_clear(self.annotations)

    if self.type == PN_RECEIVED:
      self.section_number = impl.getSectionNumber().longValue()
      self.section_offset = impl.getSectionOffset().longValue()
    else:
      self.section_number = 0
      self.section_offset = 0

    self.data.clear()
    if impl:
      # XXX
      #self.data.putObject(impl)
      pass
    self.data.rewind()

  def encode(self):
    impl = DISPOSITIONS[self.type]()

    if impl is None:
      return impl

    if self.type == PN_REJECTED:
      impl.setError(self.condition.encode())

    if self.type == PN_MODIFIED:
      impl.setDeliveryFailed(self.failed)
      impl.setUndeliverableHere(self.undeliverable)
      ann = dat2obj(self.annotations)
      if ann: impl.setMessageAnnotations(ann)

    if self.type == PN_RECEIVED:
      if self.section_number:
        impl.setSectionNumber(UnsignedInteger.valueOf(self.section_number))
      if self.section_offset:
        impl.setSectionOffset(UnsignedLong.valueOf(self.section_offset))

    return impl

def pn_disposition_type(dsp):
  return dsp.type

def pn_disposition_is_failed(dsp):
  return dsp.failed

def pn_disposition_set_failed(dsp, failed):
  dsp.failed = failed

def pn_disposition_is_undeliverable(dsp):
  return dsp.undeliverable

def pn_disposition_set_undeliverable(dsp, undeliverable):
  dsp.undeliverable = undeliverable

def pn_disposition_data(dsp):
  return dsp.data

def pn_disposition_annotations(dsp):
  return dsp.annotations

def pn_disposition_condition(dsp):
  return dsp.condition

def pn_disposition_get_section_number(dsp):
  return dsp.section_number

def pn_disposition_set_section_number(dsp, number):
  dsp.section_number = number

def pn_disposition_get_section_offset(dsp):
  return dsp.section_offset

def pn_disposition_set_section_offset(dsp, offset):
  dsp.section_offset = offset

class pn_delivery_wrapper:

  def __init__(self, impl):
    self.impl = impl
    self.local = pn_disposition()
    self.remote = pn_disposition()

def pn_delivery(link, tag):
  return wrap(link.impl.delivery(array(tag, 'b')), pn_delivery_wrapper)

def pn_delivery_tag(dlv):
  return dlv.impl.getTag().tostring()

def pn_delivery_attachments(dlv):
  return dlv.impl.attachments()

def pn_delivery_partial(dlv):
  return dlv.impl.isPartial()

def pn_delivery_pending(dlv):
  return dlv.impl.pending()

def pn_delivery_writable(dlv):
  return dlv.impl.isWritable()

def pn_delivery_readable(dlv):
  return dlv.impl.isReadable()

def pn_delivery_updated(dlv):
  return dlv.impl.isUpdated()

def pn_delivery_settled(dlv):
  return dlv.impl.remotelySettled()

def pn_delivery_local(dlv):
  dlv.local.decode(dlv.impl.getLocalState())
  return dlv.local

def pn_delivery_local_state(dlv):
  dlv.local.decode(dlv.impl.getLocalState())
  return dlv.local.type

def pn_delivery_remote(dlv):
  dlv.remote.decode(dlv.impl.getRemoteState())
  return dlv.remote

def pn_delivery_remote_state(dlv):
  dlv.remote.decode(dlv.impl.getRemoteState())
  return dlv.remote.type

def pn_delivery_update(dlv, state):
  dlv.local.type = state
  dlv.impl.disposition(dlv.local.encode())

def pn_delivery_link(dlv):
  return wrap(dlv.impl.getLink(), pn_link_wrapper)

def pn_delivery_settle(dlv):
  dlv.impl.settle()

class pn_transport_wrapper:
  def __init__(self, impl):
    self.impl = impl
    self.server = False
    self.condition = pn_condition()

def pn_transport():
  return wrap(Proton.transport(), pn_transport_wrapper)

def pn_transport_attachments(trans):
  return trans.impl.attachments()

def pn_transport_set_server(trans):
  trans.server = True;

def pn_transport_get_max_frame(trans):
  return trans.impl.getMaxFrameSize()

def pn_transport_set_max_frame(trans, value):
  trans.impl.setMaxFrameSize(value)

def pn_transport_get_remote_max_frame(trans):
  return trans.impl.getRemoteMaxFrameSize()

def pn_transport_set_idle_timeout(trans, value):
  trans.impl.setIdleTimeout(value);

def pn_transport_get_idle_timeout(trans):
  return trans.impl.getIdleTimeout()

def pn_transport_get_remote_idle_timeout(trans):
  return trans.impl.getRemoteIdleTimeout()

def pn_transport_get_frames_input(trans):
  return trans.impl.getFramesInput()

def pn_transport_get_frames_output(trans):
  return trans.impl.getFramesOutput()

def pn_transport_set_channel_max(trans, n):
  trans.impl.setChannelMax(n)

def pn_transport_get_channel_max(trans):
  return trans.impl.getChannelMax()

def pn_transport_remote_channel_max(trans):
  return trans.impl.getRemoteChannelMax()

def pn_transport_tick(trans, now):
  return trans.impl.tick(now);

def pn_transport_bind(trans, conn):
  trans.impl.bind(conn.impl)
  return 0

def pn_transport_unbind(trans):
  trans.impl.unbind()
  return 0

def pn_transport_set_pytracer(trans, tracer):
  import warnings
  warnings.warn("TODO pn_transport_set_tracer", stacklevel=2)

def pn_transport_trace(trans, n):
  trans.impl.trace(n)

def pn_transport_pending(trans):
  return trans.impl.pending()

def pn_transport_peek(trans, size):
  size = min(trans.impl.pending(), size)
  ba = zeros(size, 'b')
  if size:
    bb = trans.impl.head()
    bb.get(ba)
    bb.position(0)
  return 0, ba.tostring()

def pn_transport_pop(trans, size):
  trans.impl.pop(size)

def pn_transport_capacity(trans):
  return trans.impl.capacity()

def pn_transport_push(trans, input):
  result = 0
  while input:
    cap = pn_transport_capacity(trans)
    if cap < 0:
      return cap
    elif len(input) > cap:
      trimmed = input[:cap]
    else:
      trimmed = input

    bb = trans.impl.tail()
    bb.put(array(trimmed, 'b'))
    trans.impl.process()
    input = input[cap:]
    result += len(trimmed)
  return result

def pn_transport_close_head(trans):
  trans.impl.close_head()
  return 0

def pn_transport_close_tail(trans):
  trans.impl.close_tail()
  return 0

def pn_transport_closed(trans):
  return trans.impl.isClosed()

def pn_transport_condition(trans):
  trans.condition.decode(trans.impl.getCondition())
  return trans.condition

from org.apache.qpid.proton.engine import Event

PN_REACTOR_INIT = Event.Type.REACTOR_INIT
PN_REACTOR_QUIESCED = Event.Type.REACTOR_QUIESCED
PN_REACTOR_FINAL = Event.Type.REACTOR_FINAL

PN_TIMER_TASK = Event.Type.TIMER_TASK

PN_CONNECTION_INIT = Event.Type.CONNECTION_INIT
PN_CONNECTION_BOUND = Event.Type.CONNECTION_BOUND
PN_CONNECTION_UNBOUND = Event.Type.CONNECTION_UNBOUND
PN_CONNECTION_LOCAL_OPEN = Event.Type.CONNECTION_LOCAL_OPEN
PN_CONNECTION_REMOTE_OPEN = Event.Type.CONNECTION_REMOTE_OPEN
PN_CONNECTION_LOCAL_CLOSE = Event.Type.CONNECTION_LOCAL_CLOSE
PN_CONNECTION_REMOTE_CLOSE = Event.Type.CONNECTION_REMOTE_CLOSE
PN_CONNECTION_FINAL = Event.Type.CONNECTION_FINAL
PN_SESSION_INIT = Event.Type.SESSION_INIT
PN_SESSION_LOCAL_OPEN = Event.Type.SESSION_LOCAL_OPEN
PN_SESSION_REMOTE_OPEN = Event.Type.SESSION_REMOTE_OPEN
PN_SESSION_LOCAL_CLOSE = Event.Type.SESSION_LOCAL_CLOSE
PN_SESSION_REMOTE_CLOSE = Event.Type.SESSION_REMOTE_CLOSE
PN_SESSION_FINAL = Event.Type.SESSION_FINAL
PN_LINK_INIT = Event.Type.LINK_INIT
PN_LINK_LOCAL_OPEN = Event.Type.LINK_LOCAL_OPEN
PN_LINK_REMOTE_OPEN = Event.Type.LINK_REMOTE_OPEN
PN_LINK_LOCAL_CLOSE = Event.Type.LINK_LOCAL_CLOSE
PN_LINK_REMOTE_CLOSE = Event.Type.LINK_REMOTE_CLOSE
PN_LINK_LOCAL_DETACH = Event.Type.LINK_LOCAL_DETACH
PN_LINK_REMOTE_DETACH = Event.Type.LINK_REMOTE_DETACH
PN_LINK_FLOW = Event.Type.LINK_FLOW
PN_LINK_FINAL = Event.Type.LINK_FINAL
PN_DELIVERY = Event.Type.DELIVERY
PN_TRANSPORT = Event.Type.TRANSPORT
PN_TRANSPORT_ERROR = Event.Type.TRANSPORT_ERROR
PN_TRANSPORT_HEAD_CLOSED = Event.Type.TRANSPORT_HEAD_CLOSED
PN_TRANSPORT_TAIL_CLOSED = Event.Type.TRANSPORT_TAIL_CLOSED
PN_TRANSPORT_CLOSED = Event.Type.TRANSPORT_CLOSED
PN_SELECTABLE_INIT = Event.Type.SELECTABLE_INIT
PN_SELECTABLE_UPDATED = Event.Type.SELECTABLE_UPDATED
PN_SELECTABLE_READABLE = Event.Type.SELECTABLE_READABLE
PN_SELECTABLE_WRITABLE = Event.Type.SELECTABLE_WRITABLE
PN_SELECTABLE_EXPIRED = Event.Type.SELECTABLE_EXPIRED
PN_SELECTABLE_ERROR = Event.Type.SELECTABLE_ERROR
PN_SELECTABLE_FINAL = Event.Type.SELECTABLE_FINAL

def pn_collector():
  return Proton.collector()

def pn_connection_collect(conn, coll):
  conn.impl.collect(coll)

class pn_event:

  def __init__(self, impl):
    self.impl = impl

  def copy(self):
    return pn_event(self.impl.copy())

def pn_collector_peek(coll):
  ev = coll.peek()
  if ev:
    return pn_event(ev.copy())
  else:
    return None

def pn_collector_pop(coll):
  coll.pop()

def pn_collector_free(coll):
  pass

def pn_event_reactor(event):
  return event.impl.getReactor()

def pn_event_connection(event):
  return wrap(event.impl.getConnection(), pn_connection_wrapper)

def pn_event_session(event):
  return wrap(event.impl.getSession(), pn_session_wrapper)

def pn_event_link(event):
  return wrap(event.impl.getLink(), pn_link_wrapper)

def pn_event_delivery(event):
  return wrap(event.impl.getDelivery(), pn_delivery_wrapper)

def pn_event_transport(event):
  return wrap(event.impl.getTransport(), pn_transport_wrapper)

from org.apache.qpid.proton.engine.impl import ConnectionImpl, SessionImpl, \
  SenderImpl, ReceiverImpl, DeliveryImpl, TransportImpl
from org.apache.qpid.proton.reactor.impl import TaskImpl, SelectableImpl

J2C = {
  ConnectionImpl: "pn_connection",
  SessionImpl: "pn_session",
  SenderImpl: "pn_link",
  ReceiverImpl: "pn_link",
  DeliveryImpl: "pn_delivery",
  TransportImpl: "pn_transport",
  TaskImpl: "pn_task",
  SelectableImpl: "pn_selectable"
}

wrappers = {
  "pn_connection": lambda x: wrap(x, pn_connection_wrapper),
  "pn_session": lambda x: wrap(x, pn_session_wrapper),
  "pn_link": lambda x: wrap(x, pn_link_wrapper),
  "pn_delivery": lambda x: wrap(x, pn_delivery_wrapper),
  "pn_transport": lambda x: wrap(x, pn_transport_wrapper),
  "pn_task": lambda x: x,
  "pn_selectable": lambda x: x,
  "pn_void": lambda x: x
}

def pn_event_class(event):
  ctx = event.impl.getContext()
  return J2C.get(ctx.getClass(), "pn_void")

def pn_event_context(event):
  return wrappers[pn_event_class(event)](event.impl.getContext())

def pn_event_type(event):
  return event.impl.getEventType()

def pn_event_root(event):
  return event.impl.getRootHandler()

def pn_event_type_name(etype):
  return str(etype)

def pn_event_category(event):
  return event.impl.getCategory()

def pn_event_attachments(event):
  return event.impl.attachments()

def pn_event_copy(event):
  return event.copy()

class TypeExtender:
  def __init__(self, number):
    pass
  def next(self):
    class CustomEvent(EventType):
      def isValid(self):
        return True
    return CustomEvent()
