/*******************************************************************************
 * Copyright (c) 2019 Red Hat Inc. 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:
 * - Mickael Istria (Red Hat Inc.)
 *******************************************************************************/
package org.eclipse.pde.api.tools.internal;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceDescription;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.equinox.frameworkadmin.BundleInfo;
import org.eclipse.pde.api.tools.internal.model.ApiBaseline;
import org.eclipse.pde.api.tools.internal.model.BundleComponent;
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemTypes;
import org.eclipse.pde.core.target.ITargetDefinition;
import org.eclipse.pde.core.target.ITargetLocation;
import org.eclipse.pde.core.target.ITargetPlatformService;
import org.eclipse.pde.core.target.LoadTargetDefinitionJob;
import org.eclipse.pde.core.target.TargetBundle;
import org.eclipse.pde.internal.core.ICoreConstants;
import org.eclipse.pde.internal.core.PDECore;
import org.eclipse.pde.internal.core.target.TargetPlatformService;
import org.osgi.framework.Bundle;

public class ApiAnalysisApplication implements IApplication {

	private static class Request {
		private static final String FAIL_ON_ERROR_ARG = "failOnError"; //$NON-NLS-1$
		private static final String PROJECT_ARG = "project"; //$NON-NLS-1$
		private static final String BASELINE_ARG = "baseline"; //$NON-NLS-1$
		private static final String BASELINE_DEFAULT_VALUE = "default"; //$NON-NLS-1$
		private static final String DEPENDENCY_LIST_ARG = "dependencyList"; //$NON-NLS-1$

		private Request() {
		}

		public static Request readFromArgs(String[] params) {
			Request res = new Request();
			String currentKey = null;
			for (String param : params) {
				if (param.charAt(0) == '-') {
					if (FAIL_ON_ERROR_ARG.equals(currentKey)) {
						res.failOnError = true;
					}
					currentKey = param.substring(1);
				} else if (PROJECT_ARG.equals(currentKey)) {
					res.project = new File(param);
				} else if (BASELINE_ARG.equals(currentKey) && !BASELINE_DEFAULT_VALUE.equals(param)) {
					res.baselinePath = new File(param);
				} else if (FAIL_ON_ERROR_ARG.equals(currentKey)) {
					res.failOnError = Boolean.parseBoolean(param);
				} else if (DEPENDENCY_LIST_ARG.equals(currentKey)) {
					res.tpFile = new File(param);
				}
			}
			if (FAIL_ON_ERROR_ARG.equals(currentKey)) {
				res.failOnError = true;
			}
			return res;
		}

		public File project;
		public File baselinePath;
		public boolean failOnError;
		public File tpFile;
	}

	@Override
	public Object start(IApplicationContext context) throws Exception {
		try {
			IWorkspaceDescription desc = ResourcesPlugin.getWorkspace().getDescription();
			desc.setAutoBuilding(false);
			ResourcesPlugin.getWorkspace().setDescription(desc);
			PDECore.getDefault().getPreferencesManager().setValue(ICoreConstants.DISABLE_API_ANALYSIS_BUILDER, false);

			Request args = Request
					.readFromArgs((String[]) context.getArguments().get(IApplicationContext.APPLICATION_ARGS));
			IProject project = importProject(args.project);
			if (project == null) {
				System.err.println("Project not loaded."); //$NON-NLS-1$
				return IStatus.ERROR;
			}
			IApiBaseline baseline = setBaseline(args.baselinePath);
			if (baseline == null) {
				System.err.println("Baseline shouldn't be null."); //$NON-NLS-1$
				return IStatus.ERROR;
			}
			setTargetPlatform(args.tpFile);
			configureSeverity(project);

			project.build(IncrementalProjectBuilder.FULL_BUILD, new NullProgressMonitor());
			IMarker[] allProblemMarkers = project.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
			Predicate<IMarker> isAPIMarker = marker -> {
				try {
					return marker.getType().startsWith(ApiPlugin.PLUGIN_ID);
				} catch (CoreException e) {
					ApiPlugin.log(e);
					return false;
				}
			};
			IMarker[] allAPIProbleMarkers = Arrays.stream(allProblemMarkers) //
					.filter(isAPIMarker) //
					.toArray(IMarker[]::new);
			IMarker[] allNonAPIErrors = Arrays.stream(allProblemMarkers) //
					.filter(isAPIMarker.negate()) //
					.filter(marker -> marker.getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR) //
					.toArray(IMarker[]::new);
			if (allNonAPIErrors.length > 0) {
				System.err.println("Some blocking (most likely link/compilation) errors are present:"); //$NON-NLS-1$
				for (IMarker marker : allNonAPIErrors) {
					System.err.println("* " + marker); //$NON-NLS-1$
				}
				System.err.println("Some blocking (most likely link/compilation) errors are present ^^^"); //$NON-NLS-1$
				return 10;
			}
			// errors
			IMarker[] errorMarkers = Arrays.stream(allAPIProbleMarkers)
					.filter(marker -> marker.getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR)
					.toArray(IMarker[]::new);
			System.err.println(errorMarkers.length + " API ERRORS"); //$NON-NLS-1$
			for (IMarker marker : errorMarkers) {
				System.err.println("* " + marker); //$NON-NLS-1$
			}
			// warnings
			IMarker[] warningMarkers = Arrays.stream(allAPIProbleMarkers)
					.filter(marker -> marker.getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_WARNING)
					.toArray(IMarker[]::new);
			System.out.println(warningMarkers.length + " API warnings"); //$NON-NLS-1$
			for (IMarker marker : warningMarkers) {
				System.out.println("* " + marker); //$NON-NLS-1$
			}
			// fail
			if (args.failOnError && errorMarkers.length > 0) {
				return IStatus.ERROR;
			}
			return IStatus.OK;
		} catch (Exception e) {
			e.printStackTrace();
			return IStatus.ERROR;
		}
	}

	private void setTargetPlatform(File dependencyList) throws IOException, CoreException, InterruptedException {
		if (dependencyList != null) {
			if (!(dependencyList.isFile() && dependencyList.canRead())) {
				throw new IllegalArgumentException("dependencyList argument points to non radable file: " + dependencyList.getAbsolutePath());//$NON-NLS-1$
			}
			// File is typically the output of `mvn dependnecy:list
			// -DoutputAbsoluteArtifactFilename=true -DoutputScope=false -DoutputFile=...`
			// like
			// ```
			// The following files have been resolved:
			// p2.eclipse-plugin:org.eclipse.equinoxz.event:jar:1.5.0.v20181008-1938:/home/mistria/.m2/repository/p2/osgi/bundle/org.eclipse.equinox.event/1.5.0.v20181008-1938/org.eclipse.equinox.event-1.5.0.v20181008-1938.jar
			// p2.eclipse-plugin:org.eclipse.equinox.p2.core:jar:2.6.0.v20190215-2242:/home/mistria/.m2/repository/p2/osgi/bundle/org.eclipse.equinox.p2.core/2.6.0.v20190215-2242/org.eclipse.equinox.p2.core-2.6.0.v20190215-2242.jar
			// p2.eclipse-plugin:org.eclipse.osgi.compatibility.state:jar:1.1.400.v20190208-1533:/home/mistria/.m2/repository/p2/osgi/bundle/org.eclipse.osgi.compatibility.state/1.1.400.v20190208-1533/org.eclipse.osgi.compatibility.state-1.1.400.v20190208-1533.jar
			// ```
			ITargetPlatformService service = TargetPlatformService.getDefault();
			ITargetDefinition target = service.newTarget();
			target.setName("buildpath"); //$NON-NLS-1$
			TargetBundle[] bundles = Files.readAllLines(dependencyList.toPath()).stream()//
					.filter(line -> line.contains("jar")) //$NON-NLS-1$
					.flatMap(line -> Arrays.stream(line.split(":"))) //$NON-NLS-1$
					.filter(maybePath -> !maybePath.trim().isEmpty())
					.map(File::new)//
					.filter(File::isAbsolute)//
					.filter(File::isFile)//
					.map(absoluteFile -> {
						try {
							return new TargetBundle(absoluteFile);
						} catch (CoreException e) {
							ApiPlugin.log(e);
							return null;
						}
					}).filter(Objects::nonNull)//
					.toArray(TargetBundle[]::new);
			target.setTargetLocations(new ITargetLocation[] { new BundleListTargetLocation(bundles) });
			service.saveTargetDefinition(target);
			Job job = new LoadTargetDefinitionJob(target);
			job.schedule();
			job.join();
		}
	}

	protected void configureSeverity(IProject project) {
		Map<String, String> enforcedSeverities = new HashMap<>();
		enforcedSeverities.put(IApiProblemTypes.INCOMPATIBLE_API_COMPONENT_VERSION_REPORT_MAJOR_WITHOUT_BREAKING_CHANGE,
				ApiPlugin.VALUE_ERROR);
		enforcedSeverities.put(IApiProblemTypes.INCOMPATIBLE_API_COMPONENT_VERSION_REPORT_MINOR_WITHOUT_API_CHANGE,
				ApiPlugin.VALUE_ERROR);
		IEclipsePreferences projectNode = new ProjectScope(project).getNode(ApiPlugin.PLUGIN_ID);
		enforcedSeverities.forEach((key, value) -> {
			PDECore.getDefault().getPreferencesManager().setValue(key, value);
			projectNode.put(key, value);
		});
	}

	private IApiBaseline setBaseline(File baselinePath) throws CoreException, IOException {
		if (baselinePath == null) {
			ApiBaseline baseline = new ApiBaseline("current running application"); //$NON-NLS-1$
			for (Bundle bundle : ApiPlugin.getDefault().getBundle().getBundleContext().getBundles()) {
				if (bundle.getBundleId() != 0) {
					baseline.addApiComponents(
							new IApiComponent[] { new BundleComponent(baseline,
									FileLocator.getBundleFile(bundle).getAbsolutePath(), bundle.getBundleId()) });
				}
			}
			ApiBaselineManager.getManager().addApiBaseline(baseline);
			ApiBaselineManager.getManager().setDefaultApiBaseline(baseline.getName());
			return baseline;
		} else if (baselinePath.isFile() && baselinePath.getName().endsWith(".target")) { //$NON-NLS-1$
			ITargetPlatformService service = TargetPlatformService.getDefault();
			ITargetDefinition definition = service.getTarget(baselinePath.toURI()).getTargetDefinition();
			IStatus resolutionStatus = definition.resolve(new NullProgressMonitor());
			switch (resolutionStatus.getSeverity())
				{
				case IStatus.WARNING:
					System.out.println("WARNING resolving target platform: " + resolutionStatus.getMessage()); //$NON-NLS-1$
					break;
				case IStatus.ERROR:
					throw new CoreException(resolutionStatus);
				default: // Nothing
				}
			ApiBaseline baseline = new ApiBaseline(baselinePath.getAbsolutePath());
			for (TargetBundle bundle : definition.getAllBundles()) {
				BundleInfo bundleInfo = bundle.getBundleInfo();
				if (bundleInfo.getBundleId() != 0) {
					baseline.addApiComponents(new IApiComponent[] { new BundleComponent(baseline,
							new File(bundleInfo.getLocation()).getAbsolutePath(), bundleInfo.getBundleId()) });
				}
			}
			ApiBaselineManager.getManager().addApiBaseline(baseline);
			ApiBaselineManager.getManager().setDefaultApiBaseline(baseline.getName());
			return baseline;
		} else if (baselinePath.isDirectory()) {
			System.err.println(
					"Support for directories not implemented yet, use `default` or a `</path/to/baseline.target>` baseline for currently running application."); //$NON-NLS-1$
			return null;
		}
		return ApiBaselineManager.getManager().getDefaultApiBaseline();
	}

	private IProject importProject(File projectPath) throws CoreException {
		File dotProject = new File(projectPath, IProjectDescription.DESCRIPTION_FILE_NAME);
		if (!dotProject.isFile()) {
			System.err.println("Expected `" + dotProject.getAbsolutePath() + "` file doesn't exist."); //$NON-NLS-1$ //$NON-NLS-2$
			return null;
		}
		IProjectDescription projectDescription = ResourcesPlugin.getWorkspace()
				.loadProjectDescription(Path.fromOSString(dotProject.getAbsolutePath()));
		projectDescription.setLocation(Path.fromOSString(projectPath.getAbsolutePath()));
		IProject res = ResourcesPlugin.getWorkspace().getRoot().getProject(projectDescription.getName());
		if (res.exists()) {
			if (!res.getDescription().getLocationURI().equals(projectDescription.getLocationURI())) {
				System.err.println("Project with same name and different location exists in workspace."); //$NON-NLS-1$
				return null;
			}
			res.open(new NullProgressMonitor());
			res.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
		} else {
			res.create(projectDescription, new NullProgressMonitor());
			res.open(new NullProgressMonitor());
		}

		projectDescription = res.getDescription();
		if (Arrays.stream(res.getDescription().getBuildSpec()).map(ICommand::getBuilderName)
				.noneMatch(ApiPlugin.BUILDER_ID::equals)) {
			ICommand[] builders = new ICommand[projectDescription.getBuildSpec().length + 1];
			System.arraycopy(projectDescription.getBuildSpec(), 0, builders, 0,
					projectDescription.getBuildSpec().length);
			ICommand buildCommand = projectDescription.newCommand();
			buildCommand.setBuilderName(ApiPlugin.BUILDER_ID);
			builders[builders.length - 1] = buildCommand;
			projectDescription.setBuildSpec(builders);
			res.setDescription(projectDescription, 0, new NullProgressMonitor());
		}
		ICommand[] buildSpec = projectDescription.getBuildSpec();
		List<ICommand> newBuilders = removeManifestAndSchemaBuilders(buildSpec);
		projectDescription.setBuildSpec(
				newBuilders.toArray(new ICommand[newBuilders.size()]));
		res.setDescription(projectDescription, new NullProgressMonitor());
		return res;
	}

	private static List<ICommand> removeManifestAndSchemaBuilders(ICommand[] buildSpec) {
		// remove manifest and schema builders
		return Arrays.stream(buildSpec)
				.filter(x -> !("org.eclipse.pde.ManifestBuilder".equals(x.getBuilderName()) //$NON-NLS-1$
				|| "org.eclipse.pde.SchemaBuilder".equals(x.getBuilderName())) //$NON-NLS-1$

				).collect(Collectors.toList());
	}

	@Override
	public void stop() {
		// Nothing to do
	}

}
