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

import org.osgi.framework.Bundle;
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 symbolic 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.
     *
     * @param bundle The bundle whose version is to be returned.
     */
    public static String getBundleVersion( final Bundle bundle )
    {
        Version version = bundle.getVersion();
        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 serviceBundle <code>Bundle</code> to the registered
     *      service
     * @return <code>true</code> if the referenced service matches the
     *      target of this PID.
     */
    public boolean matchesTarget( Bundle serviceBundle )
    {
        // already unregistered
        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;
    }
}
