/*
 * 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.webconsole.plugins.upnp.internal;

import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.upnp.UPnPDevice;
import org.osgi.service.upnp.UPnPEventListener;
import org.osgi.service.upnp.UPnPService;

/**
 * The reason for having this SessionObject is the strange event delivery in UPnP. It's not possible
 * read a state variable value, but if register a listener, you will get notified when the value has
 * changed.
 */
final class SessionObject implements HttpSessionBindingListener, UPnPEventListener
{

    static final String LISTENER_CLASS = UPnPEventListener.class.getName();

    private final Map vars = new HashMap();
    private final String sessionID;
    private final Map store;
    private String udn, urn;

    private final BundleContext bc;
    private final Hashtable regProps = new Hashtable(3);
    private ServiceRegistration reg;

    SessionObject(BundleContext bc, String sessionID, Map store)
    {
        this.bc = bc;
        this.sessionID = sessionID;
        this.store = store;
    }

    /**
     * @see javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.http.HttpSessionBindingEvent)
     */
    public void valueBound(HttpSessionBindingEvent event)
    {
        store.put(sessionID, this);
    }

    /**
     * @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(javax.servlet.http.HttpSessionBindingEvent)
     */
    public final void valueUnbound(HttpSessionBindingEvent event)
    {
        unsubscribe();
        store.remove(sessionID); // remove from list of sessions
    }

    /**
     * @see org.osgi.service.upnp.UPnPEventListener#notifyUPnPEvent(java.lang.String,
     *      java.lang.String, java.util.Dictionary)
     */
    public final void notifyUPnPEvent(String deviceId, String serviceId, Dictionary events)
    {
        if (sameDevice(deviceId, serviceId))
        {
            for (Enumeration e = events.keys(); e.hasMoreElements();)
            {
                Object key = e.nextElement();
                vars.put(key, events.get(key));
            }
        }
    }

    private final boolean sameDevice(String udn, String urn)
    {
        String _udn = this.udn;
        String _urn = this.urn;
        if (_udn == null || _urn == null)
            return false; // not subscribed
        return _udn.equals(udn) && _urn.equals(urn);
    }

    final synchronized SessionObject subscribe(String udn, String urn)
    {
        if (!sameDevice(udn, urn))
        {
            unsubscribe();
            this.udn = udn;
            this.urn = urn;

            try
            {
                regProps.put(UPnPEventListener.UPNP_FILTER, bc.createFilter(//
                "(&(" + UPnPDevice.UDN + '=' + udn + ")(" + //$NON-NLS-1$ //$NON-NLS-2$
                    UPnPService.ID + '=' + urn + "))")); //$NON-NLS-1$
            }
            catch (InvalidSyntaxException e)
            { /* will not happen */
            }
            reg = bc.registerService(LISTENER_CLASS, this, regProps);
        }
        return this;
    }

    final synchronized SessionObject unsubscribe()
    {
        this.udn = this.urn = null;
        vars.clear();
        if (reg != null)
        {
            try
            {
                reg.unregister();
            }
            catch (Throwable t)
            {
                // When the bundle is stopped, the session object might remain hanging
                // in the session, until it expires. After being stopped, the framework
                // however will automatically destroy the registration. But after session
                // expires this method will be called once again and will try to 
                // unregister the service. This will throw exception, that should be caught.
            }
            reg = null;
        }
        return this;
    }

    final Object getValue(String name)
    {
        return vars.get(name);
    }

    /**
     * @see java.lang.Object#toString()
     */
    public final String toString()
    {
        StringBuffer buffer = new StringBuffer();
        buffer.append("SessionObject [sessionID=").append(sessionID) //$NON-NLS-1$
            .append(", udn=").append(udn) //$NON-NLS-1$
            .append(", urn=").append(urn) //$NON-NLS-1$
            .append(", vars=").append(vars) //$NON-NLS-1$
            .append(']');
        return buffer.toString();
    }

}
