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

import java.io.File;
import java.io.FileFilter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import org.apache.felix.bundlerepository.Property;
import org.apache.felix.bundlerepository.Resource;
import org.apache.felix.bundlerepository.impl.DataModelHelperImpl;
import org.apache.felix.bundlerepository.impl.RepositoryImpl;
import org.apache.felix.bundlerepository.impl.ResourceImpl;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;

/**
 * Index the content of a maven repository using OBR
 *
 * @goal index
 * @requiresProject false
 *
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
public final class ObrIndex extends AbstractMojo {

    /**
     * OBR Repository.
     *
     * @parameter expression="${obrRepository}"
     */
    private String obrRepository;

    /**
     * Template for urls
     *
     * @parameter expression="${urlTemplate}"
     */
    private String urlTemplate;

    /**
     * Local Repository.
     *
     * @parameter expression="${localRepository}"
     * @required
     * @readonly
     */
    private ArtifactRepository localRepository;

    public void execute() throws MojoExecutionException {
        Log log = getLog();
        try
        {
            log.info("Indexing...");

            String mavenRepository = localRepository.getBasedir();
            URI mavenRepoUri = new File(mavenRepository).toURI();

            URI repositoryXml = ObrUtils.findRepositoryXml( mavenRepository, obrRepository );

            log.info("Repository:   " + mavenRepoUri);
            log.info("OBR xml:      " + repositoryXml);
            log.info("URL template: " + urlTemplate);

            List<File> files = new ArrayList<File>();
            findAllJars( new File(mavenRepository), files );

            DataModelHelperImpl dmh = new DataModelHelperImpl();
            RepositoryImpl repository = (RepositoryImpl) dmh.repository( repositoryXml.toURL() );
            for (File file : files)
            {
                try
                {
                    ResourceImpl resource = (ResourceImpl) dmh.createResource(file.toURI().toURL());
                    if (resource != null)
                    {
                        repository.addResource(resource);
                        doTemplate(mavenRepoUri, file, resource);
                        log.info("Adding resource: " + file);
                    }
                    else
                    {
                        log.info("Ignoring non OSGi bundle: " + file);
                    }
                }
                catch (Exception e)
                {
                    log.warn("Error processing bundle: " + file + " " + e.getMessage());
                }
            }
            Writer writer = new FileWriter( new File(repositoryXml) );
            try
            {
                dmh.writeRepository( repository, writer );
            }
            finally
            {
                writer.close();
            }
        }
        catch ( Exception e )
        {
            log.warn( "Exception while updating local OBR: " + e.getLocalizedMessage(), e );
        }
    }

    protected void doTemplate(URI root, File path, ResourceImpl resource) throws IOException, URISyntaxException
    {
        path = path.getAbsoluteFile().getCanonicalFile();
        String finalUri = root.relativize(path.toURI()).toString();
        if ("maven".equals(urlTemplate))
        {
            String dir = root.relativize(path.toURI()).toString();
            String[] p = dir.split("/");
            if (p.length >= 4 && p[p.length-1].startsWith(p[p.length-3] + "-" + p[p.length-2]))
            {
                String artifactId = p[p.length-3];
                String version = p[p.length-2];
                String classifier;
                String type;
                String artifactIdVersion = artifactId + "-" + version;
                StringBuffer sb = new StringBuffer();
                if (p[p.length-1].charAt(artifactIdVersion.length()) == '-')
                {
                    classifier = p[p.length-1].substring(artifactIdVersion.length() + 1, p[p.length-1].lastIndexOf('.'));
                }
                else
                {
                    classifier = null;
                }
                type = p[p.length-1].substring(p[p.length-1].lastIndexOf('.') + 1);
                sb.append("mvn:");
                for (int j = 0; j < p.length - 3; j++)
                {
                    if (j > 0)
                    {
                        sb.append('.');
                    }
                    sb.append(p[j]);
                }
                sb.append('/').append(artifactId).append('/').append(version);
                if (!"jar".equals(type) || classifier != null)
                {
                    sb.append('/');
                    if (!"jar".equals(type))
                    {
                        sb.append(type);
                    }
                    if (classifier != null)
                    {
                        sb.append('/').append(classifier);
                    }
                }
                finalUri = sb.toString();
            }
        }
        else if (urlTemplate != null)
        {
            String dir = path.getParentFile().toURI().toURL().toString();
            if (dir.endsWith("/"))
                dir = dir.substring(0, dir.length() - 1);

            if (dir.startsWith(root.toString()))
                dir = dir.substring(root.toString().length());

            String url = urlTemplate.replaceAll("%v", "" + resource.getVersion());
            url = url.replaceAll("%s", resource.getSymbolicName());
            url = url.replaceAll("%f", path.getName());
            url = url.replaceAll("%p", dir);
            finalUri = url;
        }
        resource.put(Resource.URI, finalUri, Property.URI);
    }

    private final FileFilter filter = new FileFilter() {

        public boolean accept(File pathname) {
            return pathname.getName().endsWith("ar");
        }
    };


    private void findAllJars(File mainRoot, List<File> files) {
        List<File> roots = new ArrayList<File>();
        roots.add(mainRoot);
        while (!roots.isEmpty()) {
            File root = roots.remove(0);
            File[] children = root.listFiles();
            if (children != null) {
                for (File child : children) {
                    if (child.isFile() && filter.accept(child)) {
                        files.add(child);
                    } else if (child.isDirectory()) {
                        roots.add(child);
                    }
                }
            }
        }
    }

}
