/**
 * 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.
 */
package org.apache.camel
package scala

import reflect.Manifest
import org.apache.camel.spi.{UnitOfWork, Synchronization}
import org.apache.camel.{ExchangePattern, Message, Endpoint, Exchange}
import java.lang.{Exception, String, Class}

/**
 * Rich wrapper for Camel's Exchange implementations
 */
class RichExchange(val exchange : Exchange) extends Exchange {

  def in_=(message: Any) = exchange.getIn().setBody(message)

  def in(header:String) : Any = exchange.getIn().getHeader(header)

  def in = exchange.getIn().getBody()
  def in[T](implicit manifest: Manifest[T]) : T = exchange.getIn().getBody(manifest.erasure).asInstanceOf[T]

  def out : Any = exchange.getOut().getBody()

  def out(header:String) : Any = exchange.getOut().getHeader(header)

  def out_=(message:Any) = exchange.getOut().setBody(message)


  // Delegation methods
  //-------------------------------------------------------------------------

  def setUnitOfWork(unitOfWork: UnitOfWork) = exchange.setUnitOfWork(unitOfWork)

  def setProperty(name: String, value: Any) = exchange.setProperty(name, value)

  def setPattern(pattern: ExchangePattern) = exchange.setPattern(pattern)

  def setOut(out: Message) = exchange.setOut(out)

  def setIn(in: Message) = exchange.setIn(in)

  def setFromEndpoint(fromEndpoint: Endpoint) = exchange.setFromEndpoint(fromEndpoint)

  def setFromRouteId(routeId: String) = exchange.setFromRouteId(routeId)

  def setExchangeId(id: String) = exchange.setExchangeId(id)

  def setException(t: Throwable) = exchange.setException(t)

  def removeProperty(name: String) = exchange.removeProperty(name)

  def isTransacted = exchange.isTransacted

  def isRollbackOnly = exchange.isRollbackOnly

  def isFailed = exchange.isFailed

  def hasProperties = exchange.hasProperties

  def hasOut = exchange.hasOut

  def getUnitOfWork = exchange.getUnitOfWork

  def getProperty[T](name: String, propertyType : Class[T]) = exchange.getProperty(name, propertyType)

  def getProperty[T](name: String, defaultValue: Any, propertyType : Class[T]) = exchange.getProperty(name, defaultValue, propertyType)

  def getProperty(name: String, defaultValue: Any) = exchange.getProperty(name, defaultValue)

  def getProperty(name: String) = exchange.getProperty(name)

  def getProperties = exchange.getProperties

  def getPattern = exchange.getPattern

  def getOut[T](outType : Class[T]) = exchange.getOut(outType)

  def getOut = exchange.getOut

  def getIn[T](inType : Class[T]) = exchange.getIn(inType)

  def getIn = exchange.getIn

  def getFromEndpoint = exchange.getFromEndpoint

  def getFromRouteId = exchange.getFromRouteId

  def getExchangeId = exchange.getExchangeId

  def getException[T](exceptionType : Class[T]) = exchange.getException(exceptionType)

  def getException = exchange.getException

  def getContext = exchange.getContext

  def copy = new RichExchange(exchange.copy)

  def addOnCompletion(onCompletion: Synchronization) = exchange.addOnCompletion(onCompletion)
  
  def handoverCompletions(exchange : Exchange) = exchange.handoverCompletions(exchange)

  def handoverCompletions = exchange.handoverCompletions
}
