/* 
 * 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.felix.upnp.basedriver.tool;

import java.io.PrintStream;

import org.cybergarage.util.Debug;

import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.service.log.LogService;

import org.apache.felix.upnp.basedriver.Activator;

/* 
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class Logger implements ServiceListener {
	
	private ServiceReference rls;
	private LogService osgiLogService;
    private int level;
	private PrintStream out;
	public  final static String NEWLINE = System.getProperty("line.separator");
    public static final String ROW ="\n================REQUEST=====================\n";
    public static final String END_ROW ="--------------------------------------------";
    
	private final static String LEVEL_TO_STRING[] = new String[]{
		"",
		"ERROR [ " + Activator.bc.getBundle().getBundleId() + " ] ",
		"WARNING [ " + Activator.bc.getBundle().getBundleId() + " ] ",
		"INFO [ " + Activator.bc.getBundle().getBundleId() + " ] ",
		"DEBUG [ " + Activator.bc.getBundle().getBundleId() + " ] ",
	};
	
	
	/**
	 * Create a Logger with <code>System.out</code> as <tt>PrintStream</tt> and without 
	 * 		reporting message on both <tt>PrintStream</tt> and <tt>LogService</tt>
	 * 
	 * @param log <tt>ServiceReference</tt> to the <tt>LogService</tt> to use, 
	 * 		or null to avoid the use of this service
	 * 
	 * @see #Logger(LogService, PrintStream, boolean)
	 */
	public Logger(String levelStr){
	    this.out = System.out;
		try {
	        this.level = Integer.parseInt(levelStr);
	    } catch (Exception ex){
	    	out.println("WARNING [UPnPBaseDriver Log]: " + levelStr+" is not a valid value!");
	    	this.level=2;
	    }
 	    findService();
	}

    public void setCyberDebug(String value){
        try {
            if (Boolean.valueOf(value).booleanValue()){
                Debug.on();
                out.println("INFO [UPnPBaseDriver] Started CyberLink Debug");
            }
       } catch (Exception ex){
            out.println("WARNING [UPnPBaseDriver CyberLog]: " + value +" is not a valid value!");
        }
    }
    
    ////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////// programmatic interface ////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////
    
    public void setLogLevel(int level){
        if (level < 0 || level >4 ) throw new IllegalArgumentException("Log Level must be [0-4]");
        this.level = level;
    }
    
    public int getLogLevel(){
        return this.level;
    }
    
    
    public void setCyberDebug(boolean value){
        if (value) Debug.on();
        else Debug.off();
    }
    
    public boolean getCyberDebug(){
        return Debug.isOn();
    }
    //////////////////////////// end programmatic interface ////////////////////////////
   
    
	public final void ERROR(String message) {
	    log(1,message);
	}
	
	public final void WARNING(String message) {
	    log(2,message);
	}
	
	public final void INFO(String message) {
	    log(3,message);
	}
	
    public final void DEBUG(String message) {
        log(4,message);
    }
    
    public final void PACKET(String message) {
        log(4, new StringBuffer(ROW).append(message).append(END_ROW).toString());
    }

    /**
     * Logs a message.
     *
     * <p>The <tt>ServiceReference</tt> field and the <tt>Throwable</tt>
     * field of the <tt>LogEntry</tt> object will be set to <tt>null</tt>.
     * @param msglevel The severity of the message.
     * This should be one of the defined log levels
     * but may be any integer that is interpreted in a user defined way.
     * @param message Human readable string describing the condition or <tt>null</tt>.
     * @see #LOG_ERROR
     * @see #LOG_WARNING
     * @see #LOG_INFO
     * @see #LOG_DEBUG
     */
	public void log(int msglevel, String message) {
		synchronized (this) {
            if (msglevel <= this.level){
    			if (this.osgiLogService != null ){
    				    osgiLogService.log(msglevel, message);
    			}
    			else {
    				StringBuffer sb = new StringBuffer(Logger.LEVEL_TO_STRING[msglevel]);
    			    this.out.println(sb.append(message));
    			}
            }
		}
		
	}

	 /**
     * Logs a message with an exception.
     *
     * <p>The <tt>ServiceReference</tt> field of the <tt>LogEntry</tt> object will be set to <tt>null</tt>.
     * @param msglevel The severity of the message.
     * This should be one of the defined log levels
     * but may be any integer that is interpreted in a user defined way.
     * @param message The human readable string describing the condition or <tt>null</tt>.
     * @param exception The exception that reflects the condition or <tt>null</tt>.
     * @see #LOG_ERROR
     * @see #LOG_WARNING
     * @see #LOG_INFO
     * @see #LOG_DEBUG
     */
	public void log(int msglevel, String message, Throwable exception) {
		synchronized (this) {
            if (msglevel <= this.level){ 
    			if(this.osgiLogService != null){
    				    osgiLogService.log(msglevel, message, exception);
    			}
    			else {
    				StringBuffer sb = new StringBuffer(Logger.LEVEL_TO_STRING[msglevel]);
    			    this.out.println(sb.append(message).append(NEWLINE).append(exception));
    				exception.printStackTrace(this.out);
    			}
            }
		}
	}

	private synchronized void setLogService(ServiceReference reference){
		this.rls = reference;
		this.osgiLogService = (LogService) Activator.bc.getService(rls);
	}	
	/**
	 * This look for a <tt>LogService</tt> if it founds no <tt>LogService</tt> will register a new
	 * Listener of LogService 
	 *
	 */
	private synchronized void findService() {
		//PRE:Actually no LogService are setted and we are registered as ServiceListener 
		//		for LogService (unregisterin event)
		this.rls = Activator.bc.getServiceReference(LogService.class.getName());
		if (this.rls != null){
			this.osgiLogService = (LogService) Activator.bc.getService(rls);
		}
		try {
			Activator.bc.addServiceListener(this, 
					"(" + Constants.OBJECTCLASS	+ "=" + LogService.class.getName() + ")"
			);
		} catch (InvalidSyntaxException ignore) {}				
		//POST: We are connected to a LogService or we are registered as ServiceListener 
		//		for LogService(registering event)
	}
	
	private synchronized void releaseLogService() {
        if( osgiLogService != null)
            Activator.bc.ungetService(this.rls);
		this.rls = null;
		this.osgiLogService = null;
	}
	
	/**
	 * Used to keep track the existence of a <tt>LogService</tt>
	 * 
	 * @see ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
	 */
	public void serviceChanged(ServiceEvent e) {
		switch (e.getType()) {
			case ServiceEvent.REGISTERED: {
			    // put here code check for serviceid
				setLogService(e.getServiceReference());
			}break;
	
			case ServiceEvent.MODIFIED: 
			break;
	
			case ServiceEvent.UNREGISTERING: {				
			    // put here code check for serviceid
				releaseLogService();
			}break;
		}		
	}

	/**
	 * Stop using the <tt>LogService</tt> and listening for those service event
	 * 
	 * NOTE: All the message will be reported to <tt>PrintStream</tt>
	 *
	 */
	public void close(){	
		Activator.bc.removeServiceListener(this);
		releaseLogService();
	}
}
