/*
 * 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.clerezza.osgi.services

import org.osgi.framework.{BundleContext, Constants, ServiceEvent, ServiceListener}
import scala.collection.JavaConversions._

class ServicesDsl(bundleContext: BundleContext) {

  /**
   * returns an instance of a service exposing T
   */
  def $[T](implicit m: Manifest[T]): T = {
    getService(m.erasure.asInstanceOf[Class[T]])
  }

  private def getService[T](clazz : Class[T]) : T= {
    val serviceReference = bundleContext.getServiceReference(clazz.getName)
    if (serviceReference != null) {
      bundleContext.getService(serviceReference).asInstanceOf[T]
    } else null.asInstanceOf[T]
  }

  /**
   * executes action as soon as a service exposing T is available, if such
   * a service is already available the action is executed immedtely and the
   * method blocks until the action finished executing, otherwise the method
   * returns and action will be executed when a respective becomes available.
   */
  def doWith[T](action: T => Unit)(implicit m: Manifest[T]) {
    val clazz = m.erasure.asInstanceOf[Class[T]]
    val service = getService(clazz)
    if (service != null) {
      action(service)
    } else {
      lazy val serviceListener: ServiceListener = new ServiceListener {
          def serviceChanged(e: ServiceEvent) = {
            if (e.getType == ServiceEvent.REGISTERED) {
              bundleContext.removeServiceListener(serviceListener)
              action(bundleContext.getService(e.getServiceReference).asInstanceOf[T])
            }
          }
        }
      bundleContext.addServiceListener(serviceListener,
                       "("+Constants.OBJECTCLASS+"="+clazz.getName+")")
    }
  }

  def doWith[T,U](action: (T,U) => Unit)(implicit mt: Manifest[T], mu: Manifest[U]) {
    doWith[T] {
      t: T => {
        val clazz = mu.erasure.asInstanceOf[Class[U]]
        val service = getService(clazz)
        if (service != null) {
          action(t, service)
        } else {
          doWith[U,T] {
            (iu: U, it: T) => action(it,iu)
          }
          }
      }
    }
  }

  def doWith[T,U,V](action: (T,U,V) => Unit)(implicit mt: Manifest[T],
                        mu: Manifest[U], mv: Manifest[V]) {
    doWith[T,U] {
      (t: T, u: U) => {
        val clazz = mv.erasure.asInstanceOf[Class[V]]
        val service: V = getService(clazz)
        if (service != null) {
          action(t, u, service)
        } else {
          doWith[U,V,T] {
            (iu: U, iv: V, it: T) => action(it,iu,iv)
          }
        }
      }
    }
  }
}
