package org.apache.maven.index.creator;

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

import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.maven.index.ArtifactContext;
import org.apache.maven.index.ArtifactInfo;
import org.apache.maven.index.FlatSearchRequest;
import org.apache.maven.index.FlatSearchResponse;
import org.apache.maven.index.NexusIndexer;
import org.apache.maven.index.OSGI;
import org.apache.maven.index.context.IndexCreator;
import org.apache.maven.index.context.IndexingContext;
import org.apache.maven.index.expr.StringSearchExpression;
import org.codehaus.plexus.PlexusTestCase;
import org.codehaus.plexus.util.FileUtils;

import java.io.File;
import java.util.Arrays;
import java.util.List;

/**
 * @author Olivier Lamy
 */
public class OsgiArtifactIndexCreatorTest
    extends PlexusTestCase
{
    protected IndexCreator indexCreator;

    private NexusIndexer nexusIndexer;

    static final String INDEX_ID = "osgi-test1";

    @Override
    public void setUp()
        throws Exception
    {
        super.setUp();

        indexCreator = this.lookup( IndexCreator.class, OsgiArtifactIndexCreator.ID );

        nexusIndexer = this.lookup( NexusIndexer.class );
    }

    public void testAssertIndexCreatorComponentExists()
        throws Exception
    {
        assertNotNull( indexCreator );
    }

    public void testPopulateArtifactInfo()
        throws Exception
    {
        File artifact = new File( getBasedir(),
                                  "src/test/repo-with-osgi/org/apache/karaf/features/org.apache.karaf.features.command/2.2.2/org.apache.karaf.features.command-2.2.2.jar" );

        File pom = new File( getBasedir(),
                             "src/test/repo-with-osgi/org/apache/karaf/features/org.apache.karaf.features.command/2.2.2/org.apache.karaf.features.command-2.2.2.pom" );

        ArtifactInfo artifactInfo =
            new ArtifactInfo( "test", "org.apache.karaf.features", "org.apache.karaf.features.command", "2.2.2", null );

        ArtifactContext artifactContext = new ArtifactContext( pom, artifact, null, artifactInfo, null );

        indexCreator.populateArtifactInfo( artifactContext );

        assertNotNull( "bundleSymbolicName", artifactContext.getArtifactInfo().bundleSymbolicName );

        assertNotNull( "bundleVersion", artifactContext.getArtifactInfo().bundleVersion );

        assertNotNull( "bundleExportPackage", artifactContext.getArtifactInfo().bundleExportPackage );

        assertEquals( "org.apache.karaf.features.command", artifactContext.getArtifactInfo().bundleSymbolicName );

        assertEquals( "2.2.2", artifactContext.getArtifactInfo().bundleVersion );

        assertEquals(
            "org.apache.karaf.features.command.completers;uses:=\"org.apache.karaf.features,org.apache.karaf.shell.console,org.apache.karaf.shell.console.completer\";version=\"2.2.2\",org.apache.karaf.features.command;uses:=\"org.apache.felix.gogo.commands,org.apache.karaf.features,org.apache.karaf.shell.console,org.osgi.framework,org.apache.felix.service.command\";version=\"2.2.2\"",
            artifactContext.getArtifactInfo().bundleExportPackage );

        ArtifactInfo ai = artifactContext.getArtifactInfo();

        assertEquals( "This bundle provides the Karaf shell commands to manipulate features.", ai.bundleDescription );
        assertEquals( "Apache Karaf :: Features :: Command", ai.bundleName );
        assertEquals( "http://www.apache.org/licenses/LICENSE-2.0.txt", ai.bundleLicense );
        assertEquals( "http://www.apache.org/", ai.bundleDocUrl );

        assertEquals(
            "javax.management,javax.management.loading,org.apache.felix.gogo.commands;version=\"[0.6,1)\",org.apache.felix.service.command;status=provisional;version=\"[0.6,1)\",org.apache.karaf.features;version=\"[2.2,3)\",org.apache.karaf.shell.console;version=\"[2.2,3)\",org.apache.karaf.shell.console.completer;version=\"[2.2,3)\",org.osgi.framework;version=\"[1.5,2)\",org.osgi.service.blueprint;version=\"[1.0.0,2.0.0)\"",
            ai.bundleImportPackage );
    }


    private void indexOSGIRepo()
        throws Exception
    {

        File repo = new File( getBasedir(), "src/test/repo-with-osgi" );

        File repoIndexDir = new File( getBasedir(), "target/test/repo-with-osgi/.index/" );

        if ( repoIndexDir.exists() )
        {
            FileUtils.deleteDirectory( repoIndexDir );
        }

        repoIndexDir.mkdirs();

        List<IndexCreator> indexCreators =
            Arrays.<IndexCreator>asList( new MinimalArtifactInfoIndexCreator(), new JarFileContentsIndexCreator(),
                                         new MavenPluginArtifactInfoIndexCreator(), new OsgiArtifactIndexCreator() );

        IndexingContext indexingContext =
            nexusIndexer.addIndexingContext( INDEX_ID, INDEX_ID, repo, repoIndexDir, "http://www.apache.org",
                                             "http://www.apache.org/.index", indexCreators );
        indexingContext.setSearchable( true );
        nexusIndexer.scan( indexingContext, false );


    }

    public void testIndexOSGIRepoThenSearch()
        throws Exception
    {

        try
        {
            indexOSGIRepo();

            BooleanQuery q = new BooleanQuery();

            q.add( nexusIndexer.constructQuery( OSGI.SYMBOLIC_NAME,
                                                new StringSearchExpression( "org.apache.karaf.features.command" ) ),
                   BooleanClause.Occur.MUST );

            FlatSearchRequest request = new FlatSearchRequest( q );
            FlatSearchResponse response = nexusIndexer.searchFlat( request );

            // here only one results !
            assertEquals( 1, response.getResults().size() );

            q = new BooleanQuery();

            q.add( nexusIndexer.constructQuery( OSGI.SYMBOLIC_NAME,
                                                new StringSearchExpression( "org.apache.karaf.features.core" ) ),
                   BooleanClause.Occur.MUST );

            request = new FlatSearchRequest( q );
            response = nexusIndexer.searchFlat( request );

            // here two results !
            assertEquals( 2, response.getResults().size() );
        }
        finally
        {
            nexusIndexer.getIndexingContexts().get( INDEX_ID ).close( true );
        }
    }

    public void testIndexOSGIRepoThenSearchWithVersion()
        throws Exception
    {

        indexOSGIRepo();

        try
        {

            BooleanQuery q = new BooleanQuery();

            q.add( nexusIndexer.constructQuery( OSGI.SYMBOLIC_NAME,
                                                new StringSearchExpression( "org.apache.karaf.features.core" ) ),
                   BooleanClause.Occur.MUST );

            q.add( nexusIndexer.constructQuery( OSGI.VERSION, new StringSearchExpression( "2.2.1" ) ),
                   BooleanClause.Occur.MUST );

            FlatSearchRequest request = new FlatSearchRequest( q );
            FlatSearchResponse response = nexusIndexer.searchFlat( request );

            // here only one results as we use version
            assertEquals( 1, response.getResults().size() );
        }
        finally
        {
            nexusIndexer.getIndexingContexts().get( INDEX_ID ).close( true );
        }

    }

    public void testIndexOSGIRepoThenSearchWithExportPackage()
        throws Exception
    {

        indexOSGIRepo();

        try
        {

            BooleanQuery q = new BooleanQuery();

            q.add( nexusIndexer.constructQuery( OSGI.EXPORT_PACKAGE, new StringSearchExpression(
                "org.apache.karaf.features.command.completers" ) ), BooleanClause.Occur.MUST );

            FlatSearchRequest request = new FlatSearchRequest( q );
            FlatSearchResponse response = nexusIndexer.searchFlat( request );

            //System.out.println("results with export package query " + response.getResults() );
            assertEquals( 1, response.getResults().size() );

            ArtifactInfo ai = response.getResults().iterator().next();

            assertEquals( "org.apache.karaf.features", ai.groupId );
            assertEquals( "org.apache.karaf.features.command", ai.artifactId );
            assertEquals( "2.2.2", ai.version );
            assertEquals( "org.apache.karaf.features.command", ai.bundleSymbolicName );
            assertEquals( "2.2.2", ai.bundleVersion );

            assertEquals( "This bundle provides the Karaf shell commands to manipulate features.",
                          ai.bundleDescription );
            assertEquals( "Apache Karaf :: Features :: Command", ai.bundleName );
            assertEquals( "http://www.apache.org/licenses/LICENSE-2.0.txt", ai.bundleLicense );
            assertEquals( "http://www.apache.org/", ai.bundleDocUrl );

            assertEquals(
                "javax.management,javax.management.loading,org.apache.felix.gogo.commands;version=\"[0.6,1)\",org.apache.felix.service.command;status=provisional;version=\"[0.6,1)\",org.apache.karaf.features;version=\"[2.2,3)\",org.apache.karaf.shell.console;version=\"[2.2,3)\",org.apache.karaf.shell.console.completer;version=\"[2.2,3)\",org.osgi.framework;version=\"[1.5,2)\",org.osgi.service.blueprint;version=\"[1.0.0,2.0.0)\"",
                ai.bundleImportPackage );

        }
        finally
        {
            nexusIndexer.getIndexingContexts().get( INDEX_ID ).close( true );
        }

    }

    public void testIndexOSGIRepoThenSearchWithExportService()
        throws Exception
    {

        indexOSGIRepo();

        try
        {

            BooleanQuery q = new BooleanQuery();

            q.add( nexusIndexer.constructQuery( OSGI.EXPORT_SERVICE, new StringSearchExpression(
                "org.apache.felix.bundlerepository.RepositoryAdmin" ) ), BooleanClause.Occur.MUST );

            FlatSearchRequest request = new FlatSearchRequest( q );
            FlatSearchResponse response = nexusIndexer.searchFlat( request );

            //System.out.println("results with export package query " + response.getResults() );
            assertEquals( 1, response.getResults().size() );

            ArtifactInfo ai = response.getResults().iterator().next();
            System.out.println( "ai " + ai );

            assertEquals( "org.apache.felix", ai.groupId );
            assertEquals( "org.apache.felix.bundlerepository", ai.artifactId );
            assertEquals( "1.6.6", ai.version );
            assertEquals( "bundle", ai.packaging );
            assertEquals( "org.apache.felix.bundlerepository", ai.bundleSymbolicName );
            assertEquals( "1.6.6", ai.bundleVersion );

        }
        finally
        {
            nexusIndexer.getIndexingContexts().get( INDEX_ID ).close( true );
        }

    }

    // Export-Service: org.apache.felix.bundlerepository.RepositoryAdmin,org.osgi.service.obr.RepositoryAdmin

}
