/*******************************************************************************
 * Copyright (c) 2015, 2018 Kichwa Coders Ltd 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:
 *    Jonah Graham (Kichwa Coders) - initial API and implementation to Add support for gdb's "set substitute-path" (Bug 472765)
 *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;

import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.ICachingService;
import org.eclipse.cdt.dsf.debug.service.command.CommandCache;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.launching.GdbSourceLookupDirector;
import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MiSourceFilesInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MiSourceFilesInfo.SourceFileInfo;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;

/**
 * Default implementation of {@link IGDBSourceLookup}
 *
 * @since 5.0
 */
public class GDBSourceLookup extends CSourceLookup implements IGDBSourceLookup, IDebugSourceFiles, ICachingService {

	private static class DebugSourceFilesChangedEvent extends AbstractDMEvent<IDMContext>
			implements IDebugSourceFilesChangedEvent {
		public DebugSourceFilesChangedEvent(IDMContext context) {
			super(context);
		}
	}

	private ICommandControlService fCommand;
	private CommandFactory fCommandFactory;
	private Map<ISourceLookupDMContext, CSourceLookupDirector> fDirectors = new HashMap<>();
	/**
	 * The current set of path substitutions that have been set on GDB.
	 */
	private Map<String, String> fCachedEntries = Collections.emptyMap();

	private CommandCache fDebugSourceFilesCache;

	public GDBSourceLookup(DsfSession session) {
		super(session);
	}

	@Override
	public void initialize(final RequestMonitor rm) {
		super.initialize(new ImmediateRequestMonitor(rm) {
			@Override
			protected void handleSuccess() {
				doInitialize(rm);
			}
		});
	}

	private void doInitialize(RequestMonitor rm) {
		fCommand = getServicesTracker().getService(ICommandControlService.class);
		fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();

		fDebugSourceFilesCache = new CommandCache(getSession(), fCommand);
		fDebugSourceFilesCache.setContextAvailable(fCommand.getContext(), true);

		register(new String[] { IGDBSourceLookup.class.getName(), GDBSourceLookup.class.getName(),
				IDebugSourceFiles.class.getName() }, new Hashtable<String, String>());
		rm.done();
	}

	@Override
	public void shutdown(final RequestMonitor rm) {
		unregister();
		super.shutdown(rm);
	}

	@Override
	public void setSourceLookupDirector(ISourceLookupDMContext ctx, CSourceLookupDirector director) {
		fDirectors.put(ctx, director);
		super.setSourceLookupDirector(ctx, director);
	}

	@Override
	public void initializeSourceSubstitutions(final ISourceLookupDMContext sourceLookupCtx, final RequestMonitor rm) {
		if (!fDirectors.containsKey(sourceLookupCtx)) {
			rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE,
					"No source director configured for given context", null)); //$NON-NLS-1$ );
			rm.done();
			return;
		}
		setSubstitutePaths(sourceLookupCtx, getSubstitutionsPaths(sourceLookupCtx), rm);
	}

	private Map<String, String> getSubstitutionsPaths(ISourceLookupDMContext sourceLookupCtx) {
		CSourceLookupDirector director = fDirectors.get(sourceLookupCtx);
		if (director instanceof GdbSourceLookupDirector) {
			return ((GdbSourceLookupDirector) director).getSubstitutionsPaths();
		}
		return Collections.emptyMap();
	}

	@Override
	public void sourceContainersChanged(final ISourceLookupDMContext sourceLookupCtx,
			final DataRequestMonitor<Boolean> rm) {
		if (!fDirectors.containsKey(sourceLookupCtx)) {
			rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE,
					"No source director configured for given context", null)); //$NON-NLS-1$ );
			rm.done();
			return;
		}

		Map<String, String> entries = getSubstitutionsPaths(sourceLookupCtx);
		if (entries.equals(fCachedEntries)) {
			rm.done(false);
		} else {
			/*
			 * Issue the clear and set commands back to back so that the executor thread
			 * atomically changes the source lookup settings. Any commands to GDB issued
			 * after this call will get the new source substitute settings.
			 */
			CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) {
				@Override
				protected void handleSuccess() {
					rm.done(true);
				}
			};
			fCommand.queueCommand(fCommandFactory.createCLIUnsetSubstitutePath(sourceLookupCtx),
					new DataRequestMonitor<MIInfo>(getExecutor(), countingRm));
			initializeSourceSubstitutions(sourceLookupCtx, new RequestMonitor(getExecutor(), countingRm));
			countingRm.setDoneCount(2);
		}
	}

	protected void setSubstitutePaths(ISourceLookupDMContext sourceLookupCtx, Map<String, String> entries,
			RequestMonitor rm) {
		fCachedEntries = entries;
		CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) {
			@Override
			protected void handleCompleted() {
				// Reset the list of source files when source path substitutions change
				fDebugSourceFilesCache.reset();
				getSession().dispatchEvent(new DebugSourceFilesChangedEvent(sourceLookupCtx), getProperties());
				if (!isSuccess()) {
					/*
					 * We failed to apply the changes. Clear the cache as it does not represent the
					 * state of the backend. However we don't have a good recovery here, so on
					 * future sourceContainersChanged() calls we will simply reissue the
					 * substitutions.
					 */
					fCachedEntries = null;
				}
				rm.done();
			}
		};
		countingRm.setDoneCount(entries.size());
		for (Map.Entry<String, String> entry : entries.entrySet()) {
			fCommand.queueCommand(
					fCommandFactory.createMISetSubstitutePath(sourceLookupCtx, entry.getKey(), entry.getValue()),
					new DataRequestMonitor<MIInfo>(getExecutor(), countingRm));
		}

	}

	private static final class DebugSourceFileInfo implements IDebugSourceFileInfo {
		private final SourceFileInfo miInfo;

		private DebugSourceFileInfo(SourceFileInfo miInfo) {
			if (miInfo == null)
				throw new IllegalArgumentException("The SourceFileInfo provided is null"); //$NON-NLS-1$
			this.miInfo = miInfo;
		}

		@Override
		public String getName() {
			// we get the file name without the path
			String name = miInfo != null ? miInfo.getFile() : null;
			if (name == null)
				return name;
			try {
				Path p = Paths.get(name);
				name = p.getFileName() != null ? p.getFileName().toString() : ""; //$NON-NLS-1$
			} catch (InvalidPathException e) {
				// do nothing
			}
			return name;
		}

		@Override
		public String getPath() {
			// we get the file name without the path
			String path = miInfo != null ? miInfo.getFullName() : null;
			if (path == null)
				return path;
			try {
				Path p = Paths.get(path);
				path = p.toString();
			} catch (InvalidPathException e) {
				// do nothing
			}
			return path;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + ((miInfo == null) ? 0 : miInfo.hashCode());
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			DebugSourceFileInfo other = (DebugSourceFileInfo) obj;
			if (miInfo == null) {
				if (other.miInfo != null)
					return false;
			} else if (!miInfo.equals(other.miInfo))
				return false;
			return true;
		}

		@Override
		public String toString() {
			return "DebugSourceFileInfo [miInfo=" + miInfo + "]"; //$NON-NLS-1$ //$NON-NLS-2$
		}

	}

	@Override
	public void getSources(final IDMContext dmc, final DataRequestMonitor<IDebugSourceFileInfo[]> rm) {
		fDebugSourceFilesCache.execute(fCommandFactory.createMiFileListExecSourceFiles(dmc),
				new DataRequestMonitor<MiSourceFilesInfo>(getExecutor(), rm) {
					@Override
					protected void handleSuccess() {
						IDebugSourceFileInfo[] result = null;
						MiSourceFilesInfo sourceFiles = getData();
						SourceFileInfo[] info = sourceFiles.getSourceFiles();
						result = Arrays.asList(info).stream().map(DebugSourceFileInfo::new)
								.toArray(IDebugSourceFileInfo[]::new);
						rm.setData(result);
						rm.done();
					}
				});
	}

	@Override
	public void flushCache(IDMContext context) {
		fDebugSourceFilesCache.reset();
		getSession().dispatchEvent(new DebugSourceFilesChangedEvent(fCommand.getContext()), getProperties());
	}
}
