/*
 * 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.
 */
/*
 * Contributor(s): theanuradha@netbeans.org
 */

package org.netbeans.modules.maven.indexer;

import java.io.File;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.maven.index.ArtifactContext;
import org.apache.maven.index.ArtifactScanningListener;
import org.apache.maven.index.ScanningResult;
import org.apache.maven.index.context.IndexingContext;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.modules.maven.indexer.api.RepositoryInfo;
import org.netbeans.modules.maven.indexer.api.RepositoryPreferences;
import org.openide.util.Cancellable;
import org.openide.util.NbBundle.Messages;

public class RepositoryIndexerListener implements ArtifactScanningListener, Cancellable {

    private final IndexingContext indexingContext;
    private int count;
    private ProgressHandle handle;
    private final AtomicBoolean canceled = new AtomicBoolean();
    private final RepositoryInfo ri;
    private final Set<File> expectedDirs = new HashSet<File>();
    private final Set<File> encounteredDirs = new HashSet<File>();

    @SuppressWarnings("LeakingThisInConstructor")
    public RepositoryIndexerListener(IndexingContext indexingContext) {
        this.indexingContext = indexingContext;
        ri = RepositoryPreferences.getInstance().getRepositoryInfoById(indexingContext.getId());
        Cancellation.register(this);
    }

    @Messages({
        "# {0} - repo name", "LBL_indexing_repo=Indexing Maven repository: {0}",
        "LBL_findIndexableDirs=Counting indexable directories..."
    })
    @Override public void scanningStarted(IndexingContext ctx) {
        if (handle != null) {
            handle.finish();
        }
        expectedDirs.clear();
        encounteredDirs.clear();
        handle = ProgressHandle.createHandle(Bundle.LBL_indexing_repo(ri != null ? ri.getName() : indexingContext.getId()), this);
        handle.start();
        handle.progress(Bundle.LBL_findIndexableDirs());
        findIndexableDirs(ctx.getRepository());
        handle.switchToDeterminate(expectedDirs.size());
    }
    
    private void findIndexableDirs(File d) {
        // Try to guess what DefaultScanner might find. Hard to know for sure, so guess that nonempty leaf dirs will contain real artifacts.
        if (d == null || d.getName().startsWith(".")) {
            return;
        }
        File[] kids = d.listFiles();
        if (kids == null) {
            return;
        }
        boolean hasFiles = false;
        boolean hasDirs = false;
        for (File f : kids) {
            if (f.isFile() && !f.getName().matches("maven-metadata.*[.]xml")) {
                hasFiles = true;
            }
            if (f.isDirectory()) {
                hasDirs = true;
                findIndexableDirs(f);
            }
        }
        if (hasFiles && !hasDirs) {
            expectedDirs.add(d);
        }
    }

    public @Override boolean cancel() {
        return canceled.compareAndSet(false, true);
    }

    @Override public void artifactDiscovered(ArtifactContext ac) {
        if (canceled.get()) {
            throw new Cancellation();
        }
        count++;
        if (handle != null) {
            String label = ac.getArtifactInfo().getGroupId() + ":" + ac.getArtifactInfo().getArtifactId() + ":" + ac.getArtifactInfo().getVersion();
            File art = ac.getArtifact();
            if (art == null) {
                art = ac.getPom();
            }
            if (art != null) {
                File d = art.getParentFile();
                if (expectedDirs.contains(d)) {
                    encounteredDirs.add(d);
                }
            }
            handle.progress(label, encounteredDirs.size());
        }
    }

    @Override public void artifactError(ArtifactContext ac, Exception e) {
        if (canceled.get()) {
            throw new Cancellation();
        }
    }

    @Override public void scanningFinished(IndexingContext ctx, ScanningResult result) {
//        Set<File> unencountered = new TreeSet<File>(expectedDirs);
//        unencountered.removeAll(encounteredDirs);
//        System.err.println("did not encounter " + unencountered.size() + ":");
//        for (File d : unencountered) {
//            System.err.println("  " + d);
//        }
    }

    void close() {
        if (handle != null) {
            handle.finish();
        }
    }
}
