/*
 * 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.scr.impl;

import org.apache.felix.scr.impl.config.ComponentHolder;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.Version;

/**
 * Copied with modifications from felix configadmin.
 * 
 * The <code>TargetedPID</code> class represents a targeted PID as read
 * from a configuration object.
 * <p>
 * For a factory configuration the <code>TargetedPID</code> represents
 * the factory PID of the configuration. Otherwise it represents the
 * PID itself of the configuration.
 */
public class TargetedPID
{

    private final String rawPid;

    private final String servicePid;

    private final String symbolicName;
    private final String version;
    private final String location;

    /**
     * The level of binding of this targeted PID:
     * <ul>
     * <li><code>0</code> -- this PID is not targeted at all</li>
     * <li><code>1</code> -- this PID is targeted by the symbolic name</li>
     * <li><code>2</code> -- this PID is targeted by the symbolic name and version</li>
     * <li><code>3</code> -- this PID is targeted by the symoblic name, version, and location</li>
     * </ul>
     */
    private final short bindingLevel;


    /**
     * Returns the bundle's version as required for targeted PIDs: If the
     * bundle has a version the string representation of the version
     * string converted to a Version object is returned. Otherwise the
     * string representation of <code>Version.emptyVersion</code> is
     * returned.
     * <p>
     * To remain compatible with pre-R4.2 (Framework API < 1.5) we cannot
     * use the <code>Bundle.getVersion()</code> method.
     *
     * @param bundle The bundle whose version is to be returned.
     */
    public static String getBundleVersion( final Bundle bundle )
    {
        Object vHeader = bundle.getHeaders().get( Constants.BUNDLE_VERSION );
        Version version = ( vHeader == null ) ? Version.emptyVersion : new Version( vHeader.toString() );
        return version.toString();
    }


    public TargetedPID( final String rawPid )
    {
        this.rawPid = rawPid;

        if ( rawPid.indexOf( '|' ) < 0 )
        {
            this.servicePid = rawPid;
            this.symbolicName = null;
            this.version = null;
            this.location = null;
            this.bindingLevel = 0;
        }
        else
        {
            int start = 0;
            int end = rawPid.indexOf( '|' );
            this.servicePid = rawPid.substring( start, end );

            start = end + 1;
            end = rawPid.indexOf( '|', start );
            if ( end >= 0 )
            {
                this.symbolicName = rawPid.substring( start, end );
                start = end + 1;
                end = rawPid.indexOf( '|', start );
                if ( end >= 0 )
                {
                    this.version = rawPid.substring( start, end );
                    this.location = rawPid.substring( end + 1 );
                    this.bindingLevel = 3;
                }
                else
                {
                    this.version = rawPid.substring( start );
                    this.location = null;
                    this.bindingLevel = 2;
                }
            }
            else
            {
                this.symbolicName = rawPid.substring( start );
                this.version = null;
                this.location = null;
                this.bindingLevel = 1;
            }
        }
    }


    /**
     * Returns true if the target of this PID (bundle symbolic name,
     * version, and location) match the bundle registering the referenced
     * service.
     * <p>
     * This method just checks the target not the PID value itself, so
     * this method returning <code>true</code> does not indicate whether
     * the service actually is registered with a service PID equal to the
     * raw PID of this targeted PID.
     * <p>
     * This method also returns <code>false</code> if the service has
     * concurrently been unregistered and the registering bundle is now
     * <code>null</code>.
     *
     * @param reference <code>ServiceReference</code> to the registered
     *      service
     * @return <code>true</code> if the referenced service matches the
     *      target of this PID.
     */
    public boolean matchesTarget( ComponentHolder holder )
    {
        // already unregistered
        final Bundle serviceBundle = holder.getActivator().getBundleContext().getBundle();
        if ( serviceBundle == null )
        {
            return false;
        }

        // This is not really targeted
        if ( this.symbolicName == null )
        {
            return true;
        }

        // bundle symbolic names don't match
        if ( !this.symbolicName.equals( serviceBundle.getSymbolicName() ) )
        {
            return false;
        }

        // no more specific target
        if ( this.version == null )
        {
            return true;
        }

        // bundle version does not match

        if ( !this.version.equals( getBundleVersion( serviceBundle ) ) )
        {
            return false;
        }

        // assert bundle location match
        return this.location == null || this.location.equals( serviceBundle.getLocation() );
    }


    /**
     * Gets the raw PID with which this instance has been created.
     * <p>
     * If an actual service PID contains pipe symbols that PID might be
     * considered being targeted PID without it actually being one. This
     * method provides access to the raw PID to allow for such services to
     * be configured.
     */
    public String getRawPid()
    {
        return rawPid;
    }


    /**
     * Returns the service PID of this targeted PID which basically is
     * the targeted PID without the targeting information.
     */
    public String getServicePid()
    {
        return servicePid;
    }


    /**
     * Returns <code>true</code> if this targeted PID binds stronger than
     * the <code>other</code> {@link TargetedPID}.
     * <p>
     * This method assumes both targeted PIDs have already been checked for
     * suitability for the bundle encoded in the targetting.
     *
     * @param other The targeted PID to check whether it is binding stronger
     *      or not.
     * @return <code>true</code> if the <code>other</code> targeted PID
     *      is binding strong.
     */
    public boolean bindsStronger( final TargetedPID other )
    {
        return other == null || this.bindingLevel > other.bindingLevel;
    }


    @Override
    public int hashCode()
    {
        return this.rawPid.hashCode();
    }


    @Override
    public boolean equals( Object obj )
    {
        if ( obj == null )
        {
            return false;
        }
        else if ( obj == this )
        {
            return true;
        }

        // assume equality if same class and raw PID equals
        if ( this.getClass() == obj.getClass() )
        {
            return this.rawPid.equals( ( ( TargetedPID ) obj ).rawPid );
        }

        // not the same class or different raw PID
        return false;
    }


    @Override
    public String toString()
    {
        return this.rawPid;
    }
}
