/*******************************************************************************
 * Copyright (c) 2008, 2017 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
t https://www.eclipse.org/legal/epl-2.0/
t
t SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors: IBM Corporation - initial API and implementation
 ******************************************************************************/

package org.eclipse.pde.internal.build.publisher;

import java.io.File;
import java.util.*;
import java.util.jar.JarFile;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.PatternSet.NameEntry;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.p2.publisher.PublisherInfo;
import org.eclipse.pde.build.Constants;
import org.eclipse.pde.internal.build.IBuildPropertiesConstants;
import org.eclipse.pde.internal.build.Utils;
import org.eclipse.pde.internal.build.builder.ModelBuildScriptGenerator;
import org.eclipse.pde.internal.build.builder.ModelBuildScriptGenerator.CompiledEntry;

public class GatherBundleTask extends AbstractPublisherTask {
	static final private String API_DESCRIPTION = ".api_description"; //$NON-NLS-1$

	static public class OutputFileSet extends FileSet {
		private String library;

		public OutputFileSet() {
			super();
		}

		public String getLibrary() {
			return this.library;
		}

		public void setLibrary(String value) {
			this.library = value;
		}

		@Override
		public synchronized void setIncludes(String includes) {
			super.setIncludes(includes);
		}
	}

	private String buildResultFolder = null;
	private String targetFolder = null;
	private String gatheredSource = null;
	private String unpack = null;
	private final Map<String, Set<OutputFileSet>> sourceMap = new HashMap<>();

	@Override
	public void execute() throws BuildException {
		GatheringComputer computer = createComputer();

		GatherBundleAction action = null;
		if (targetFolder != null) {
			File targetFile = new File(targetFolder);
			action = new GatherBundleAction(targetFile, targetFile);
		} else
			action = new GatherBundleAction(new File(baseDirectory), new File(buildResultFolder));
		action.setComputer(computer);
		action.setUnpack(unpack);

		PublisherInfo info = getPublisherInfo();
		BuildPublisherApplication application = createPublisherApplication();
		application.addAction(action);
		try {
			application.run(info);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	protected GatheringComputer createComputer() {
		Properties properties = getBuildProperties();
		GatheringComputer computer = new GatheringComputer();

		if (targetFolder != null) {
			FileSet fileSet = new FileSet();
			fileSet.setProject(getProject());
			fileSet.setDir(new File(targetFolder));
			NameEntry includes = fileSet.createInclude();
			includes.setName("**"); //$NON-NLS-1$
			NameEntry excludes = fileSet.createExclude();
			excludes.setName(JarFile.MANIFEST_NAME);

			if (new File(targetFolder, JarFile.MANIFEST_NAME).exists())
				computer.addFile(targetFolder, JarFile.MANIFEST_NAME);
			computer.addFiles(targetFolder, fileSet.getDirectoryScanner().getIncludedFiles());
			return computer;
		}

		CompiledEntry[] entries = null;
		try {
			entries = ModelBuildScriptGenerator.extractEntriesToCompile(properties, null);
		} catch (CoreException e) {
			//nothing being compiled?
		}

		int numIncludes = 0;
		String include = (String) properties.get(IBuildPropertiesConstants.PROPERTY_BIN_INCLUDES);
		String[] splitIncludes = Utils.getArrayFromString(include);
		String exclude = (String) properties.get(IBuildPropertiesConstants.PROPERTY_BIN_EXCLUDES);

		FileSet fileSet = new FileSet();
		fileSet.setProject(getProject());
		fileSet.setDir(new File(baseDirectory));

		for (int i = 0; i < splitIncludes.length; i++) {
			String entry = splitIncludes[i];
			if (entry.equals(ModelBuildScriptGenerator.DOT))
				continue;

			NameEntry fileInclude = fileSet.createInclude();
			fileInclude.setName(entry);
			++numIncludes;
		}

		if (numIncludes > 0) {
			//we want to exclude the manifest and compiled libraries from this set, they are added separately
			String extraExcludes = JarFile.MANIFEST_NAME;
			for (int i = 0; entries != null && i < entries.length; i++) {
				String name = entries[i].getName(false);
				if (!name.equals(ModelBuildScriptGenerator.DOT)) {
					String formatedName = name + (entries[i].getType() == CompiledEntry.FOLDER ? "/" : ""); //$NON-NLS-1$//$NON-NLS-2$
					extraExcludes += "," + formatedName; //$NON-NLS-1$
				}
			}

			String[] splitExcludes = Utils.getArrayFromString(exclude != null ? exclude + "," + extraExcludes : extraExcludes); //$NON-NLS-1$
			for (int i = 0; i < splitExcludes.length; i++) {
				NameEntry fileExclude = fileSet.createExclude();
				fileExclude.setName(splitExcludes[i]);
			}

			List<String> includedFiles = Arrays.asList(fileSet.getDirectoryScanner().getIncludedFiles());
			LinkedHashSet<String> set = new LinkedHashSet<>(includedFiles);

			// Manifest must go first, and must have been specifically excluded earlier from the buildResultFolder to not get added.
			if (new File(buildResultFolder, JarFile.MANIFEST_NAME).exists())
				computer.addFile(buildResultFolder, JarFile.MANIFEST_NAME);

			// The plugin.xml and fragment.xml may have had versions changed, take them from the buildResultFolder
			if (set.contains(Constants.PLUGIN_FILENAME_DESCRIPTOR) && new File(buildResultFolder, Constants.PLUGIN_FILENAME_DESCRIPTOR).exists()) {
				set.remove(Constants.PLUGIN_FILENAME_DESCRIPTOR);
				computer.addFile(buildResultFolder, Constants.PLUGIN_FILENAME_DESCRIPTOR);
			}
			if (set.contains(Constants.FRAGMENT_FILENAME_DESCRIPTOR) && new File(buildResultFolder, Constants.FRAGMENT_FILENAME_DESCRIPTOR).exists()) {
				set.remove(Constants.FRAGMENT_FILENAME_DESCRIPTOR);
				computer.addFile(buildResultFolder, Constants.FRAGMENT_FILENAME_DESCRIPTOR);
			}

			if (new File(buildResultFolder, API_DESCRIPTION).exists())
				computer.addFile(buildResultFolder, API_DESCRIPTION);

			//everything else
			computer.addFiles(baseDirectory, set.toArray(new String[set.size()]));
		}

		boolean dotIncluded = false;
		if (entries != null) {
			//add all the compiled libraries
			boolean haveEntries = false;
			fileSet = new FileSet();
			fileSet.setProject(getProject());
			fileSet.setDir(new File(buildResultFolder));
			for (int i = 0; i < entries.length; i++) {
				String name = entries[i].getName(false);
				if (name.equals(ModelBuildScriptGenerator.DOT)) {
					dotIncluded = true;
					continue;
				}

				if (sourceMap.containsKey(name) && entries[i].getType() == CompiledEntry.FOLDER) {
					Set<OutputFileSet> folders = sourceMap.get(name);
					processOutputFolders(folders, name, computer);
				} else {
					NameEntry fileInclude = fileSet.createInclude();
					fileInclude.setName(name + ((entries[i].getType() == CompiledEntry.FOLDER) ? "/" : "")); //$NON-NLS-1$ //$NON-NLS-2$
					haveEntries = true;
				}
			}
			if (haveEntries) {
				computer.addFiles(buildResultFolder, fileSet.getDirectoryScanner().getIncludedFiles());
			}
		}

		if (dotIncluded) {
			//special handling for '.'
			if (sourceMap.containsKey(ModelBuildScriptGenerator.DOT)) {
				Set<OutputFileSet> folders = sourceMap.get(ModelBuildScriptGenerator.DOT);
				processOutputFolders(folders, ModelBuildScriptGenerator.DOT, computer);
			} else {
				fileSet = new FileSet();
				fileSet.setProject(getProject());
				fileSet.setDir(new File(buildResultFolder, ModelBuildScriptGenerator.EXPANDED_DOT));
				NameEntry fileInclude = fileSet.createInclude();
				fileInclude.setName("**"); //$NON-NLS-1$
				if (exclude != null) {
					String[] splitExcludes = Utils.getArrayFromString(exclude);
					for (int i = 0; i < splitExcludes.length; i++) {
						NameEntry fileExclude = fileSet.createExclude();
						fileExclude.setName(splitExcludes[i]);
					}
				}

				computer.addFiles(buildResultFolder + '/' + ModelBuildScriptGenerator.EXPANDED_DOT, fileSet.getDirectoryScanner().getIncludedFiles());
			}
		}

		if (gatheredSource != null) {
			File sourceFile = new File(gatheredSource);
			if (sourceFile.exists()) {
				fileSet = new FileSet();
				fileSet.setProject(getProject());
				fileSet.setDir(sourceFile);
				NameEntry fileInclude = fileSet.createInclude();
				fileInclude.setName("**"); //$NON-NLS-1$
				computer.addFiles(gatheredSource, fileSet.getDirectoryScanner().getIncludedFiles());
			}
		}

		return computer;
	}

	private void processOutputFolders(Set<OutputFileSet> folders, String key, GatheringComputer computer) {
		boolean dot = key.equals(ModelBuildScriptGenerator.DOT);
		for (Iterator<OutputFileSet> iterator = folders.iterator(); iterator.hasNext();) {
			OutputFileSet outputFiles = iterator.next();
			File baseDir = outputFiles.getDir();
			String[] includes = outputFiles.mergeIncludes(getProject());
			//handling more than one include here would involve correlating the includes files
			//with the pattern that included them.
			if (includes.length == 1) {
				IPath prefix = new Path(includes[0]).removeLastSegments(1);
				int count = prefix.segmentCount();
				String[] files = outputFiles.getDirectoryScanner().getIncludedFiles();
				for (int i = 0; i < files.length; i++) {
					IPath suffix = new Path(files[i]).removeFirstSegments(count);
					String computerPath = dot ? suffix.toString() : key + '/' + suffix.toString();
					computer.addFile(computerPath, new File(baseDir, files[i]));
				}
			}
		}
	}

	public void setBuildResultFolder(String buildResultFolder) {
		this.buildResultFolder = buildResultFolder;
	}

	public void setUnpack(String unpack) {
		if (unpack != null && unpack.length() > 0 && !unpack.startsWith(ANT_PREFIX))
			this.unpack = unpack;
	}

	public void setGatheredSource(String gatheredSource) {
		if (gatheredSource != null && gatheredSource.length() > 0 && !gatheredSource.startsWith(ANT_PREFIX))
			this.gatheredSource = gatheredSource;
	}

	public void setTargetFolder(String targetFolder) {
		if (targetFolder != null && targetFolder.length() > 0 && !targetFolder.startsWith(ANT_PREFIX))
			this.targetFolder = targetFolder;
	}

	public void addConfiguredOutputFolder(OutputFileSet output) {
		String key = output.getLibrary();
		if (sourceMap.containsKey(key)) {
			Set<OutputFileSet> set = sourceMap.get(key);
			set.add(output);
		} else {
			Set<OutputFileSet> set = new HashSet<>();
			set.add(output);
			sourceMap.put(key, set);
		}
	}
}
