/*
 * 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.netbeans.api.java.queries;

import java.net.URL;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.event.ChangeListener;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.modules.java.classpath.QueriesAccessor;
import org.netbeans.spi.java.queries.BinaryForSourceQueryImplementation;
import org.netbeans.spi.java.queries.BinaryForSourceQueryImplementation2;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.filesystems.URLMapper;
import org.openide.util.Lookup;

/**
 *
 * The query is used for finding binaries for sources,
 * this is intended to be the inverse of the {@link SourceForBinaryQuery}.
 * @see BinaryForSourceQueryImplementation2
 * @see BinaryForSourceQueryImplementation
 * @see SourceForBinaryQuery
 * @since org.netbeans.api.java/1 1.12
 * @author Tomas Zezula
 * 
 */
public final class BinaryForSourceQuery {
    
    
    private static final Logger LOG = Logger.getLogger(BinaryForSourceQuery.class.getName());
    
    
    /** Creates a new instance of BInaryForSOurceQuery */
    private BinaryForSourceQuery() {
    }
    
    /**
     * Returns the binary root for given source root.
     * @param sourceRoot the source path root. The URL must refer to folder. 
     * In the case of archive file the jar protocol URL must be used.
     * The folder URL has to end with '/' The {@link FileUtil#urlForArchiveOrDir}
     * can be used to create folder URLs.
     * @return a result object encapsulating the answer (never null)
     */
    public static Result findBinaryRoots (final URL sourceRoot) {
       assert sourceRoot != null;
       for (BinaryForSourceQueryImplementation impl : Lookup.getDefault().lookupAll(BinaryForSourceQueryImplementation.class)) {
           BinaryForSourceQuery.Result result = impl.findBinaryRoots (sourceRoot);
           if (result != null) {
               if (LOG.isLoggable(Level.FINE)) {
                    LOG.log(
                        Level.FINE,
                        "findBinaryRoots({0}) -> {1} from {2}", //NOI18N
                        new Object[] {
                            sourceRoot,
                            Arrays.asList(result.getRoots()),
                            impl});
                }
               return result;
           }
       }
       LOG.log(
           Level.FINE,
           "findBinaryRoots({0}) -> nil",  //NOI18N
           sourceRoot);
       return new DefaultResult (sourceRoot);
    }

    /**
     * Returns the binary root for given source root as computed by {@link BinaryForSourceQueryImplementation2}.
     * @param sourceRoot the source path root. The URL must refer to folder.
     * In the case of archive file the jar protocol URL must be used.
     * The folder URL has to end with '/' The {@link FileUtil#urlForArchiveOrDir}
     * can be used to create folder URLs.
     * @return a result object encapsulating the answer (never null)
     * @since 1.58
     */
    public static Result2 findBinaryRoots2(URL sourceRoot) {
        return QueriesAccessor.wrap(findBinaryRoots(sourceRoot));
    }
    
    /**
     * Result of finding binaries, encapsulating the answer as well as the
     * ability to listen to it.
     */
    public static interface Result {
        
        /**
         * Get the binary roots.         
         * @return array of roots of compiled classes (may be empty but not null)
         */
        URL[] getRoots();
        
        /**
         * Add a listener to changes in the roots.
         * @param l a listener to add
         */
        void addChangeListener(ChangeListener l);
        
        /**
         * Remove a listener to changes in the roots.
         * @param l a listener to remove
         */
        void removeChangeListener(ChangeListener l);
    }

    /** Enhanced version of {@link Result} obtained via
     * {@link BinaryForSourceQuery#findBinaryRoots2(java.net.URL)} method.
     * Use {@link BinaryForSourceQueryImplementation2} to create instance
     * of this class.
     * @since 1.58
     */
    public static abstract class Result2 implements Result {
        Result2() {
        }

        /**
         * Check whether the binaries should be prefered over sources.
         * Return {@code true} if the classes (if newer than sources) shall be
         * copied instead of compiling the sources by the IDE.
         * @return true or false
         * @since 1.58
         */
        public abstract boolean preferBinaries();
    }
    
    private static class DefaultResult extends Result2 {
        
        private final URL sourceRoot;
        
        DefaultResult (final URL sourceRoot) {
            this.sourceRoot = sourceRoot;
        }
    
        @Override
        public URL[] getRoots() {
            FileObject fo = URLMapper.findFileObject(sourceRoot);
            if (fo == null) {
                return new URL[0];
            }
            ClassPath exec = ClassPath.getClassPath(fo, ClassPath.EXECUTE);
            if (exec == null) {
                return new URL[0];
            }           
            Set<URL> result = new HashSet<>();
            for (ClassPath.Entry e : exec.entries()) {
                final URL eurl = e.getURL();
                FileObject[] roots = SourceForBinaryQuery.findSourceRoots(eurl).getRoots();
                for (FileObject root : roots) {
                        if (sourceRoot.equals (root.toURL())) {
                            result.add (eurl);
                        }
                }
            }
            return result.toArray(new URL[result.size()]);
        }

        @Override
        public void addChangeListener(ChangeListener l) {            
        }

        @Override
        public void removeChangeListener(ChangeListener l) {            
        }

        @Override
        public boolean preferBinaries() {
            return false;
        }
    }

    private static final class Result2Impl<T> extends Result2 {
        final BinaryForSourceQueryImplementation2<T> impl;
        final T value;

        Result2Impl(BinaryForSourceQueryImplementation2<T> impl, T value) {
            this.impl = impl;
            this.value = value;
        }

        @Override
        public boolean preferBinaries() {
            return impl.computePreferBinaries(value);
        }

        @Override
        public URL[] getRoots() {
            return impl.computeRoots(value);
        }

        @Override
        public void addChangeListener(ChangeListener l) {
            impl.computeChangeListener(value, true, l);
        }

        @Override
        public void removeChangeListener(ChangeListener l) {
            impl.computeChangeListener(value, false, l);
        }


    }
    
    static final QueriesAccessorImpl CACHE = new QueriesAccessorImpl();
    static {
        QueriesAccessor.setInstance(CACHE);
    }

    static final class QueriesAccessorImpl extends QueriesAccessor {
        QueriesAccessorImpl() {
        }
        private final Map<Object, Result2Impl<?>> cache = new WeakHashMap<>();

        @Override
        public synchronized <T> Result2 create(BinaryForSourceQueryImplementation2<T> impl, T value) {
            Result2Impl<?> result = cache.get(value);
            if (result == null) {
                result = new Result2Impl<>(impl, value);
                cache.put(value, result);
            }
            assert impl == result.impl;
            return result;
        }

        synchronized Object findRegistered(Object prototype) {
            for (Object object : cache.keySet()) {
                if (prototype.equals(object)) {
                    return object;
                }
            }
            return null;
        }
    }
}
