/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.launching;


import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jdt.internal.launching.DefaultProjectClasspathEntry;
import org.eclipse.jdt.internal.launching.VariableClasspathEntry;

/**
 * Default implementation of source lookup path computation and resolution.
 * <p>
 * This class may be sub-classed.
 * </p>
 * @since 2.0
 */
public class StandardSourcePathProvider extends StandardClasspathProvider {

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.launching.IRuntimeClasspathProvider#computeUnresolvedClasspath(org.eclipse.debug.core.ILaunchConfiguration)
	 */
	@Override
	public IRuntimeClasspathEntry[] computeUnresolvedClasspath(ILaunchConfiguration configuration) throws CoreException {
		boolean useDefault = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_SOURCE_PATH, true);
		IRuntimeClasspathEntry[] entries = null;
		if (useDefault) {
			// the default source lookup path is the same as the classpath
			entries = super.computeUnresolvedClasspath(configuration);
		} else {
			// recover persisted source path
			entries = recoverRuntimePath(configuration, IJavaLaunchConfigurationConstants.ATTR_SOURCE_PATH);
		}
		return entries;

	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.launching.IRuntimeClasspathProvider#resolveClasspath(org.eclipse.jdt.launching.IRuntimeClasspathEntry[], org.eclipse.debug.core.ILaunchConfiguration)
	 */
	@Override
	public IRuntimeClasspathEntry[] resolveClasspath(IRuntimeClasspathEntry[] entries, ILaunchConfiguration configuration) throws CoreException {
		List<IRuntimeClasspathEntry> all = new UniqueList(entries.length);
		for (int i = 0; i < entries.length; i++) {
			switch (entries[i].getType()) {
				case IRuntimeClasspathEntry.PROJECT:
					// a project resolves to itself for source lookup (rather than the class file output locations)
					all.add(entries[i]);
					break;
				case IRuntimeClasspathEntry.OTHER:
					IRuntimeClasspathEntry2 entry = (IRuntimeClasspathEntry2)entries[i];
					String typeId = entry.getTypeId();
					IRuntimeClasspathEntry[] res = null;
					if (typeId.equals(DefaultProjectClasspathEntry.TYPE_ID)) {
						// add the resolved children of the project
						IRuntimeClasspathEntry[] children = entry.getRuntimeClasspathEntries(configuration);
						res = JavaRuntime.resolveSourceLookupPath(children, configuration);
					} else if (typeId.equals(VariableClasspathEntry.TYPE_ID)) {
						// add the archive itself - we currently do not allow a source attachment
						res = JavaRuntime.resolveRuntimeClasspathEntry(entry, configuration);
					} else {
                        res = JavaRuntime.resolveRuntimeClasspathEntry(entry, configuration);
                    }
					if (res != null) {
						for (int j = 0; j < res.length; j++) {
							all.add(res[j]);
                            addManifestReferences(res[j], all);
						}
					}
					break;
				default:
					IRuntimeClasspathEntry[] resolved =JavaRuntime.resolveRuntimeClasspathEntry(entries[i], configuration);
					for (int j = 0; j < resolved.length; j++) {
						all.add(resolved[j]);
                        addManifestReferences(resolved[j], all);
					}
					break;
			}
		}
		return all.toArray(new IRuntimeClasspathEntry[all.size()]);
	}

    /**
     * If the given entry is an archive, adds any archives referenced by the associated manifest.
     *
     * @param entry runtime classpath entry
     * @param all list to add references to
     */
    protected void addManifestReferences(IRuntimeClasspathEntry entry, List<IRuntimeClasspathEntry> all) {
        if (entry.getType() == IRuntimeClasspathEntry.ARCHIVE) {
            String location = entry.getLocation();
            if (location != null) {
				try (JarFile jar = new JarFile(location, false);) {
                    Manifest manifest = jar.getManifest();
                    if (manifest != null) {
                        Attributes mainAttributes = manifest.getMainAttributes();
                        if (mainAttributes != null) {
                            String value = mainAttributes.getValue(Attributes.Name.CLASS_PATH);
                            if (value != null) {
                                String[] entries = value.split("\\s+"); //$NON-NLS-1$
                                IPath base = new Path(location);
                                base = base.removeLastSegments(1);
                                for (int i = 0; i < entries.length; i++) {
                                    IPath path = base.append(entries[i]);
                                    if (path.toFile().exists()) {
                                        IRuntimeClasspathEntry ref = JavaRuntime.newArchiveRuntimeClasspathEntry(path);
                                        if (!all.contains(ref)) {
                                            all.add(ref);
                                        }
                                    }
                                }
                            }
                        }
                    }
                } catch (IOException e) {
				}
            }
        }
    }

    /*
     * An ArrayList that acts like a set -i.e. does not allow duplicate items.
     * hack for bug 112774
     */
    class UniqueList extends ArrayList<IRuntimeClasspathEntry> {
        private static final long serialVersionUID = -7402160651027036270L;
        HashSet<IRuntimeClasspathEntry> set;

        public UniqueList(int length) {
            super(length);
            set = new HashSet<>(length);
        }

        @Override
		public void add(int index, IRuntimeClasspathEntry element) {
            if (set.add(element)) {
				super.add(index, element);
			}
        }

        @Override
		public boolean add(IRuntimeClasspathEntry o) {
            if (set.add(o)) {
				return super.add(o);
			}
            return false;
        }

        @Override
        public boolean addAll(Collection<? extends IRuntimeClasspathEntry> c) {
        	if (set.addAll(c)) {
				return super.addAll(c);
			}
            return false;
        }

        @Override
		public boolean addAll(int index, Collection<? extends IRuntimeClasspathEntry> c) {
            if (set.addAll(c)) {
				return super.addAll(index, c);
			}
            return false;
        }

        @Override
		public void clear() {
            set.clear();
            super.clear();
        }

        @Override
		public boolean contains(Object elem) {
            return set.contains(elem);
        }

        @Override
		public void ensureCapacity(int minCapacity) {
            super.ensureCapacity(minCapacity);
        }

        @Override
		public IRuntimeClasspathEntry remove(int index) {
            IRuntimeClasspathEntry object = super.remove(index);
            set.remove(object);
            return object;
        }

        @Override
		protected void removeRange(int fromIndex, int toIndex) {
            for (int index = fromIndex; index<=toIndex; index++) {
				remove(index);
			}
        }

        @Override
		public IRuntimeClasspathEntry set(int index, IRuntimeClasspathEntry element) {
            set.remove(element);
            if (set.add(element)) {
				return super.set(index, element);
			}
            return null; //should not happen.
        }
    }

}
