/*******************************************************************************
 * 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;
					switch (typeId) {
						case DefaultProjectClasspathEntry.TYPE_ID:
							// add the resolved children of the project
							IRuntimeClasspathEntry[] children = entry.getRuntimeClasspathEntries(configuration);
							res = JavaRuntime.resolveSourceLookupPath(children, configuration);
							break;
						case VariableClasspathEntry.TYPE_ID:
							// add the archive itself - we currently do not allow a source attachment
							res = JavaRuntime.resolveRuntimeClasspathEntry(entry, configuration);
							break;
						default:
							res = JavaRuntime.resolveRuntimeClasspathEntry(entry, configuration);
							break;
					}
					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.
        }
    }

}
