/**
 *  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.maven.mercury.artifact;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.maven.mercury.artifact.version.DefaultArtifactVersion;
import org.apache.maven.mercury.artifact.version.VersionException;
import org.apache.maven.mercury.artifact.version.VersionRange;
import org.apache.maven.mercury.artifact.version.VersionRangeFactory;
import org.codehaus.plexus.lang.DefaultLanguage;
import org.codehaus.plexus.lang.Language;

/**
 * this is the most primitive metadata there is, usually used to query repository for "real" metadata. It holds
 * everything a project.dependencies.dependency element can have
 * 
 * @author Oleg Gusakov
 * @version $Id$
 */
public class ArtifactMetadata
{
    public static final String DEFAULT_ARTIFACT_TYPE = "jar";

    private static final Language LANG = new DefaultLanguage( ArtifactMetadata.class );

    /**
     * standard glorified artifact coordinates
     */
    protected String groupId;

    protected String artifactId;

    private String version;

    private transient VersionRange versionRange;

    private Quality quality;

    /**
     * relocation chain after processing by ProjectBuilder
     */
    protected List<ArtifactCoordinates> relocations;

    protected ArtifactCoordinates effectiveCoordinates;

    // This is Maven specific. jvz/
    protected String classifier;

    protected String type = DEFAULT_ARTIFACT_TYPE;

    protected ArtifactScopeEnum artifactScope;

//    protected String scope;

    protected boolean optional;

    protected Collection<ArtifactMetadata> inclusions;

    protected Collection<ArtifactMetadata> exclusions;

    protected Map<String, String> attributes;

    /** conveniency for SNAPSHOT file timestamp */
    private String timeStamp;

    /**
     * transient helper objects, used by DependencyBuilder.
     */
    transient Object tracker;

    transient Boolean local = false;

    /**
     * transient external datum to carry along
     */
    transient Object datum;

    /** dependencies of the artifact behind this metadata */
    protected List<ArtifactMetadata> dependencies;

    /** artifact URI */
    protected String artifactUri;

    // ------------------------------------------------------------------
    public ArtifactMetadata()
    {
    }

    // ------------------------------------------------------------------
    private void processAttributes( String as )
    {
        if ( as == null || as.length() < 1 )
        {
            return;
        }

        String attrString = as.trim();

        if ( attrString == null || attrString.length() < 1 )
        {
            return;
        }

        int fromCh = attrString.indexOf( '{' );
        int toCh = attrString.indexOf( '}' );

        if ( fromCh != -1 && toCh != -1 )
        {
            attrString = attrString.substring( fromCh + 1, toCh );
        }

        String[] entries = attrString.split( "," );

        if ( entries != null )
        {
            for ( int i = 0; i < entries.length; i++ )
            {
                String e = entries[i];

                if ( e == null )
                {
                    continue;
                }

                int eq = e.indexOf( '=' );

                if ( eq == -1 )
                {
                    continue;
                }

                if ( attributes == null )
                {
                    attributes = new LinkedHashMap<String, String>( entries.length );
                }

                String name = e.substring( 0, eq );

                if ( name == null )
                {
                    continue;
                }

                name = name.trim();

                String val = e.substring( eq + 1 );

                if ( val != null )
                {
                    val = val.trim();
                }

                attributes.put( name, val );
            }
        }
    }

    // ------------------------------------------------------------------
    /**
     * create basic out of <b>group:artifact:version:classifier:type</b> string, use empty string to specify missing
     * component - for instance query for common-1.3.zip can be specified as ":common:1.3::zip" - note missing groupId
     * and classifier.
     */
    public ArtifactMetadata( String gavQuery )
    {
        if ( gavQuery == null )
        {
            return;
        }

        String[] tokens = gavQuery.split( ":" );

        if ( tokens == null || tokens.length < 1 )
        {
            return;
        }

        int count = tokens.length;

        this.groupId = nullify( tokens[0] );

        if ( count > 1 )
        {
            this.artifactId = nullify( tokens[1] );
        }

        if ( count > 2 )
        {
            this.version = nullify( tokens[2] );
        }

        if ( count > 3 )
        {
            this.classifier = nullify( tokens[3] );
        }

        if ( count > 4 )
        {
            setType( nullify( tokens[4] ) );
        }

        if ( this.type == null || this.type.length() < 1 )
        {
            this.type = DEFAULT_ARTIFACT_TYPE;
        }

        if ( count > 5 )
        {
            this.artifactScope = ArtifactScopeEnum.valueOf( nullify( tokens[5] ) );
        }

        if ( count > 6 )
        {
            processAttributes( nullify( tokens[6] ) );
        }
    }

    /**
     * copy constructor
     * 
     * @param copyFrom
     */
    public ArtifactMetadata( ArtifactMetadata copyFrom )
    {
        if ( copyFrom == null )
            throw new IllegalArgumentException( LANG.getMessage( "null.copy.from.md" ) );

        setGroupId( copyFrom.getGroupId() );
        setArtifactId( copyFrom.getArtifactId() );
        setVersion( copyFrom.getVersion() );
        setClassifier( copyFrom.getClassifier() );
        setType( copyFrom.getType() );
        setScope( copyFrom.getScope() );

        Map<String, String> a = copyFrom.getAttributes();
        if ( a != null && a.size() > 0 )
        {
            attributes = new HashMap<String, String>( a.size() );

            attributes.putAll( a );
        }

        setTracker( copyFrom.getTracker() );

    }

    // ------------------------------------------------------------------
    /**
     * create basic out of <b>group:artifact:version:classifier:type</b> string, use empty string to specify missing
     * component - for instance query for common-1.3.zip can be specified as ":common:1.3::zip" - note missing groupId
     * and classifier.
     */
    public static ArtifactMetadata create( String query )
    {
        ArtifactMetadata mdq = new ArtifactMetadata( query );

        return mdq;
    }

    // ---------------------------------------------------------------------------
    private static final String nullify( String s )
    {
        if ( s == null || s.length() < 1 )
        {
            return null;
        }
        return s;
    }

    // ---------------------------------------------------------------------
    public boolean sameGAV( ArtifactMetadata md )
    {
        if ( md == null )
        {
            return false;
        }

        return sameGA( md ) && version != null && version.equals( md.getVersion() );
    }

    // ---------------------------------------------------------------------
    public boolean sameGA( ArtifactMetadata md )
    {
        if ( md == null )
        {
            return false;
        }

        return groupId != null && artifactId != null && groupId.equals( md.getGroupId() )
            && artifactId.equals( md.getArtifactId() );
    }

    public String getGA()
    {
        return toDomainString();
    }

    public String getGAV()
    {
        return toString();
    }

    private static final String nvl( String val, String dflt )
    {
        return val == null ? dflt : val;
    }

    private static final String nvl( String val )
    {
        return nvl( val, "" );
    }

    @Override
    public String toString()
    {
        return nvl( groupId ) + ":" + nvl( artifactId ) + ":" + nvl( version ) + ":" + nvl( classifier ) + ":"
            + nvl( type, DEFAULT_ARTIFACT_TYPE );
    }

    public String toScopedString()
    {
        return toString() + "-scope:" + getArtifactScope();
    }

    public String toDomainString()
    {
        return groupId + ":" + artifactId;
    }

    public String toManagementString()
    {
        return groupId + ":" + artifactId + ":" + type + ( classifier != null ? ":" + classifier : "" );
    }

    public String getBaseName()
    {
        return artifactId + "-" + version + ( classifier == null ? "" : "-" + classifier );
    }

    public String getFileName()
    {
        return getBaseName() + "." + ( type == null ? DEFAULT_ARTIFACT_TYPE : type );
    }

    public String getBaseName( String classifier )
    {
        return artifactId + "-" + version
            + ( ( classifier == null || classifier.length() < 1 ) ? "" : "-" + classifier );
    }

    public String getCheckedType()
    {
        return type == null ? "jar" : type;
    }

    // ---------------------------------------------------------------------------
    public String getGroupId()
    {
        return groupId;
    }

    public void setGroupId( String groupId )
    {
        this.groupId = groupId;
    }

    public String getArtifactId()
    {
        return artifactId;
    }

    public void setArtifactId( String artifactId )
    {
        this.artifactId = artifactId;
    }

    public String getVersion()
    {
        return version;
    }

    public boolean hasVersion()
    {
        return version != null && version.length() > 0;
    }

    public void setVersion( String version )
    {
        this.version = version;
    }

    private void checkRangeExists()
    {
        if ( versionRange == null )
        {
            if ( version == null )
                throw new IllegalArgumentException( LANG.getMessage( "artifact.metadata.no.version", toString() ) );
            else
            {
                try
                {
                    versionRange = VersionRangeFactory.create( version );
                }
                catch ( VersionException e )
                {
                    throw new IllegalArgumentException( e.getMessage() );
                }
            }
        }
    }

    public boolean isSingleton()
    {
        checkRangeExists();

        return versionRange.isSingleton();
    }

    public boolean isRange()
    {
        return !isSingleton();
    }

    /** code quality used to decide whether try or skip a repository - see repository code quality */
    public Quality getRequestedQuality()
    {
        if ( isRange() )
            return null;

        if ( isVirtual() )
        {
            if ( isVirtualSnapshot() )
                return Quality.SNAPSHOT_QUALITY;
            else if ( isVirtualRelease() )
                return Quality.RELEASE_QUALITY;

            return null;
        }

        if ( quality != null )
            return quality;

        quality = new Quality( getVersion() );

        return quality;
    }

    public String getClassifier()
    {
        return classifier;
    }

    public void setClassifier( String classifier )
    {
        this.classifier = classifier;
    }

    public String getType()
    {
        return type;
    }

    public void setType( String type )
    {
        if ( "test-jar".equals( type ) )
        {
            setClassifier( "tests" );
            setType( "jar" );
        }
        else
            this.type = type;
    }

    public Map<String, String> getAttributes()
    {
        return attributes;
    }

    public String getScope()
    {
        return getArtifactScope().getScope();
    }

    public ArtifactScopeEnum getScopeAsEnum()
    {
        return artifactScope == null ? ArtifactScopeEnum.DEFAULT_SCOPE : artifactScope;
    }

    public ArtifactScopeEnum getArtifactScope()
    {
        return artifactScope == null ? ArtifactScopeEnum.DEFAULT_SCOPE : artifactScope;
    }

    public void setArtifactScope( ArtifactScopeEnum artifactScope )
    {
        this.artifactScope = artifactScope;
    }

    public void setScope( String scope )
    {
        this.artifactScope = scope == null ? ArtifactScopeEnum.DEFAULT_SCOPE : ArtifactScopeEnum.valueOf( scope );
    }

    public boolean isOptional()
    {
        return optional;
    }

    public void setOptional( boolean optional )
    {
        this.optional = optional;
    }

    public void setOptional( String optional )
    {
        this.optional = "true".equals( optional );
    }

    public Object getTracker()
    {
        return tracker;
    }

    public void setTracker( Object tracker )
    {
        this.tracker = tracker;
    }

    public boolean hasClassifier()
    {
        return classifier != null && classifier.length() > 0;
    }

    public Boolean isLocal()
    {
        return local;
    }

    public void setLocal( Boolean local )
    {
        this.local = local;
    }

    public boolean isPom()
    {
        return "pom".regionMatches( 0, type, 0, 3 );
    }

    public boolean isVirtual()
    {
        return DefaultArtifactVersion.isVirtual( version );
    }

    public boolean isVirtualSnapshot()
    {
        return DefaultArtifactVersion.isVirtualSnapshot( version );
    }

    public boolean isVirtualRelease()
    {
        return DefaultArtifactVersion.isVirtualRelease( version );
    }

    public boolean isVirtualLatest()
    {
        return DefaultArtifactVersion.isVirtualLatest( version );
    }

    public ArtifactCoordinates getEffectiveCoordinates()
    {
        if ( relocations == null || relocations.isEmpty() )
        {
            return new ArtifactCoordinates( groupId, artifactId, version );
        }

        return relocations.get( relocations.size() - 1 );
    }

    public ArtifactMetadata addRelocation( ArtifactCoordinates coord )
    {
        if ( coord == null )
        {
            return this;
        }

        if ( relocations == null )
        {
            relocations = new ArrayList<ArtifactCoordinates>( 2 );
        }

        if ( coord.getGroupId() == null )
        {
            coord.setGroupId( groupId );
        }

        if ( coord.getArtifactId() == null )
        {
            coord.setArtifactId( artifactId );
        }

        if ( coord.getVersion() == null )
        {
            coord.setVersion( version );
        }

        relocations.add( coord );
        effectiveCoordinates = coord;

        return this;
    }

    public String getEffectiveGroupId()
    {
        return effectiveCoordinates == null ? groupId : effectiveCoordinates.getGroupId();
    }

    public String getEffectiveArtifactId()
    {
        return effectiveCoordinates == null ? artifactId : effectiveCoordinates.getArtifactId();
    }

    public String getEffectiveersion()
    {
        return effectiveCoordinates == null ? version : effectiveCoordinates.getVersion();
    }

    public boolean hasInclusions()
    {
        return inclusions == null ? false : !inclusions.isEmpty();
    }

    public Collection<ArtifactMetadata> getInclusions()
    {
        return inclusions;
    }

    public void setInclusions( Collection<ArtifactMetadata> inclusions )
    {
        this.inclusions = inclusions;
    }

    public boolean hasExclusions()
    {
        return exclusions == null ? false : !exclusions.isEmpty();
    }

    public Collection<ArtifactMetadata> getExclusions()
    {
        return exclusions;
    }

    public void setExclusions( Collection<ArtifactMetadata> exclusions )
    {
        this.exclusions = exclusions;
    }

    /**
     * run dependency through inclusion/exclusion filters. Inclusion filter is always a "hole"-filter, which is then
     * enhanced by exclusion "cork"-filter
     * 
     * @param dep dependency to vet
     * @return vet result
     * @throws VersionException
     */
    public boolean allowDependency( ArtifactMetadata dep )
        throws VersionException
    {
        boolean includeDependency = true;
        if ( hasInclusions() )
        {
            includeDependency = !passesFilter( inclusions, dep );
        }

        if ( !includeDependency )
        {
            return false;
        }

        if ( !hasExclusions() )
        {
            return true;
        }

        if ( passesFilter( exclusions, dep ) )
        {
            return true;
        }

        return false;

    }

    private boolean passesFilter( Collection<ArtifactMetadata> filter, ArtifactMetadata dep )
        throws VersionException
    {
        for ( ArtifactMetadata filterMd : filter )
        {
            if ( filterMd.sameGA( dep ) )
            {
                if ( !filterMd.hasVersion() )
                {
                    return false; // no version in the filter - catch by GA
                }
                VersionRange vr = VersionRangeFactory.create( filterMd.getVersion() );
                if ( vr.includes( dep.getVersion() ) )
                {
                    return false; // catch by version query
                }
            }
        }

        return true;
    }

    @Override
    public boolean equals( Object obj )
    {
        if ( obj == null || !( obj instanceof ArtifactMetadata ) )
        {
            return false;
        }

        return toString().equals( obj.toString() );
    }

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

    public List<ArtifactMetadata> getDependencies()
    {
        return dependencies;
    }

    public void setDependencies( List<ArtifactMetadata> dependencies )
    {
        this.dependencies = dependencies;
    }

    public String getArtifactUri()
    {
        return artifactUri;
    }

    public void setArtifactUri( String artifactUri )
    {
        this.artifactUri = artifactUri;
    }

    public Object getDatum()
    {
        return datum;
    }

    public void setDatum( Object datum )
    {
        this.datum = datum;
    }

    public String getTimeStamp()
    {
        return timeStamp;
    }

    public void setTimeStamp( String timeStamp )
    {
        this.timeStamp = timeStamp;
    }

    // ---------------------------------------------------------------------------
    // ---------------------------------------------------------------------------
}
