/*******************************************************************************
 * Copyright (c) 2004, 2016 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     IBH SYSTEMS GmbH - allow removing the consoles
 *******************************************************************************/
package org.eclipse.releng.tools;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.osgi.util.NLS;
import org.eclipse.releng.tools.preferences.RelEngCopyrightConstants;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.RepositoryProviderType;
import org.eclipse.ui.IActionDelegate;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleConstants;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.console.MessageConsoleStream;

public class AdvancedFixCopyrightAction implements IObjectActionDelegate {

	final class FixConsole extends MessageConsole {
		private FixConsole() {
			super(Messages.getString("AdvancedFixCopyrightAction.0"), null); //$NON-NLS-1$
		}
	}
	
	private static final int UNIT_OF_WORK = 1;
	
	public class FixCopyrightVisitor implements IResourceVisitor {
		private final IProgressMonitor monitor;
		private final RepositoryProviderCopyrightAdapter adapter;

		public FixCopyrightVisitor(RepositoryProviderCopyrightAdapter adapter,
				IProgressMonitor monitor) {
			this.adapter = adapter;
			this.monitor = monitor;
		}

		public boolean visit(IResource resource) throws CoreException {
			if (!monitor.isCanceled()) {
				if (resource.getType() == IResource.FILE) {
					monitor.subTask(((IFile) resource).getFullPath().toOSString());
					processFile((IFile) resource, adapter, monitor);
					monitor.worked(UNIT_OF_WORK);
				} 
			}
			return true;
		}
	}
	
	/**
	 * Visit each file to count total number of files that we will traverse. 
	 * This is used to show the progress correctly. 
	 */
	private class FileCountVisitor implements IResourceVisitor {
		private int fileCount;
		
		public FileCountVisitor() {
			this.fileCount = 0;
		}

		public boolean visit(IResource resource) throws CoreException {
			if (resource.getType() == IResource.FILE) {
				fileCount += UNIT_OF_WORK;
			}
			return true;
		}
		
		public int getfileCount() {
			return this.fileCount;
		}
	}

	private String newLine = System.getProperty("line.separator"); //$NON-NLS-1$
	private Map<String, List<String>> log = new HashMap<String, List<String>>();
	private MessageConsole console;

	// The current selection
	protected IStructuredSelection selection;

	private static final int currentYear = new GregorianCalendar().get(Calendar.YEAR);

	/**
	 * Returns the selected resources.
	 * 
	 * @return the selected resources
	 */
	protected IResource[] getSelectedResources() {
		ArrayList<IResource> resources = null;
		if (!selection.isEmpty()) {
			resources = new ArrayList<IResource>();
			Iterator<?> elements = selection.iterator();
			while (elements.hasNext()) {
				addResource(elements.next(), resources);
			}
		}
		if (resources != null && !resources.isEmpty()) {
			IResource[] result = new IResource[resources.size()];
			resources.toArray(result);
			return result;
		}
		return new IResource[0];
	}

	private void addResource(Object element, ArrayList<IResource> resources) {
		if (element instanceof IResource) {
			resources.add((IResource) element);
		} else if (element instanceof IWorkingSet) {
			IWorkingSet ws = (IWorkingSet) element;
			IAdaptable[] elements= ws.getElements();
			for (int i= 0; i < elements.length; i++)
				addResource(elements[i], resources);
		} else if (element instanceof IAdaptable) {
			IAdaptable a = (IAdaptable) element;
			addResource(a.getAdapter(IResource.class), resources);
		}
	}

	/**
	 * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
	 */
	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
	}

	/**
	 * @see IActionDelegate#run(IAction)
	 */
	public void run(IAction action) {
		log = new HashMap<String, List<String>>();
		console = new FixConsole();
		ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] {console});
		try {
			PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(IConsoleConstants.ID_CONSOLE_VIEW);
		} catch (PartInitException e) {
			// Don't fail if we can't show the console
			RelEngPlugin.log(e);
		}
		final MessageConsoleStream stream = console.newMessageStream();

		WorkspaceJob wJob = new WorkspaceJob(Messages.getString("AdvancedFixCopyrightAction.1")) { //$NON-NLS-1$
			@Override
			public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
				try {
					long start = System.currentTimeMillis();
					stream.println(Messages.getString("AdvancedFixCopyrightAction.2")); //$NON-NLS-1$
					IResource[] results = getSelectedResources();
					stream.println(NLS.bind(
							Messages.getString("AdvancedFixCopyrightAction.3"), Integer.toString(results.length))); //$NON-NLS-1$
					
					monitor.subTask(Messages.getString("AdvancedFixCopyrightAction.22")); //'initializing' msg. //$NON-NLS-1$
					int totalFileCount = countFiles(results);	//this generates ~5% overhead. 
					monitor.beginTask(Messages.getString("AdvancedFixCopyrightAction.4"), totalFileCount); //$NON-NLS-1$

					RepositoryProviderCopyrightAdapter adapter = createCopyrightAdapter(results);
					if(adapter == null) {
						if(!RelEngPlugin.getDefault().getPreferenceStore().getBoolean(RelEngCopyrightConstants.USE_DEFAULT_REVISION_YEAR_KEY)) {
							throw new CoreException(new Status(IStatus.ERROR, RelEngPlugin.ID, 0, Messages.getString("AdvancedFixCopyrightAction.5"), null)); //$NON-NLS-1$
						}
					} else {
						adapter.initialize(SubMonitor.convert(monitor, 100));
					}
					List<CoreException> exceptions = new ArrayList<CoreException>();
					for (int i = 0; i < results.length; i++) {
						IResource resource = results[i];
						stream.println(NLS.bind(
								Messages.getString("AdvancedFixCopyrightAction.6"), resource.getName())); //$NON-NLS-1$
						try {
							resource.accept(new FixCopyrightVisitor(adapter, monitor));
						} catch (CoreException e1) {
							exceptions.add(e1);
						}
					}

					writeLogs();
					displayLogs(stream);
					stream.println(Messages.getString("AdvancedFixCopyrightAction.7")); //$NON-NLS-1$
					long end = System.currentTimeMillis();
					stream.println(NLS.bind(
							Messages.getString("AdvancedFixCopyrightAction.8"), Long.toString(end - start))); //$NON-NLS-1$
					if (!exceptions.isEmpty()) {
						stream.println(Messages.getString("AdvancedFixCopyrightAction.9")); //$NON-NLS-1$
						if (exceptions.size() == 1) {
							throw exceptions.get(0);
						} else {
							List<Status> status = new ArrayList<Status>();
							for (Iterator<CoreException> iterator = exceptions.iterator(); iterator
									.hasNext();) {
								CoreException ce = iterator.next();
								status.add(new Status(
										ce.getStatus().getSeverity(), 
										ce.getStatus().getPlugin(),
										ce.getStatus().getCode(),
										ce.getStatus().getMessage(),
										ce));
							}
							throw new CoreException(new MultiStatus(RelEngPlugin.ID,
									0, status.toArray(new IStatus[status.size()]),
									Messages.getString("AdvancedFixCopyrightAction.10"), //$NON-NLS-1$
									null));
						}
					}
				} finally {
					monitor.done();
				}
				return Status.OK_STATUS;
			}
			
			private int countFiles(IResource[] results) {
				int sum = 0;
				for (IResource file : results) {
					FileCountVisitor fileCountVisitor = new FileCountVisitor();
					try {
						file.accept(fileCountVisitor);
					} catch (CoreException e) {
						//This exception can be ignored.
						//Here we are only counting files.
						//It will be handled when files are actually
						//proccessed. 
					}
					sum += fileCountVisitor.getfileCount();
				}
				return sum;
			}
		};

		wJob.setRule(ResourcesPlugin.getWorkspace().getRoot());
		wJob.setUser(true);
		wJob.schedule();
	}

	protected RepositoryProviderCopyrightAdapter createCopyrightAdapter(
			IResource[] results) throws CoreException {
		RepositoryProviderType providerType = null;
		for (int i = 0; i < results.length; i++) {
			IResource resource = results[i];
			RepositoryProvider p = RepositoryProvider.getProvider(resource.getProject());
			if (p != null) {
				if (providerType == null) {
					providerType = RepositoryProviderType.getProviderType(p.getID());
				} else if (!providerType.getID().equals(p.getID())) {
					throw new CoreException(new Status(IStatus.ERROR, RelEngPlugin.ID, 0, Messages.getString("AdvancedFixCopyrightAction.11"), null)); //$NON-NLS-1$
				}
			}
		}
		if(providerType == null) {
			return null;
		}
		IRepositoryProviderCopyrightAdapterFactory factory = providerType.getAdapter(IRepositoryProviderCopyrightAdapterFactory.class);
		if (factory == null) {
			factory = (IRepositoryProviderCopyrightAdapterFactory)Platform.getAdapterManager().loadAdapter(providerType, IRepositoryProviderCopyrightAdapterFactory.class.getName());
			if (factory == null) {
				throw new CoreException(new Status(IStatus.ERROR, RelEngPlugin.ID, 0, NLS.bind(Messages.getString("AdvancedFixCopyrightAction.12"), providerType.getID()), null)); //$NON-NLS-1$
			}
		}
		return factory.createAdapater(results);
	}

	/**
	 *  
	 */
	private void writeLogs() {

		FileOutputStream aStream;
		try {
			File aFile = new File(Platform.getLocation().toFile(),
					"copyrightLog.txt"); //$NON-NLS-1$
			aStream = new FileOutputStream(aFile);
			Set<Map.Entry<String, List<String>>> aSet = log.entrySet();
			Iterator<Map.Entry<String, List<String>>> errorIterator = aSet.iterator();
			while (errorIterator.hasNext()) {
				Map.Entry<String, List<String>> anEntry = errorIterator.next();
				String errorDescription = anEntry.getKey();
				aStream.write(errorDescription.getBytes());
				aStream.write(newLine.getBytes());
				List<String> fileList = anEntry.getValue();
				Iterator<String> listIterator = fileList.iterator();
				while (listIterator.hasNext()) {
					String fileName = listIterator.next();
					aStream.write("     ".getBytes()); //$NON-NLS-1$
					aStream.write(fileName.getBytes());
					aStream.write(newLine.getBytes());
				}
			}
			aStream.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void displayLogs(MessageConsoleStream stream) {

		Set<Map.Entry<String, List<String>>> aSet = log.entrySet();
		Iterator<Map.Entry<String, List<String>>> errorIterator = aSet.iterator();
		while (errorIterator.hasNext()) {
			Map.Entry<String, List<String>> anEntry = errorIterator.next();
			String errorDescription = anEntry.getKey();
			stream.println(errorDescription);
			List<String> fileList = anEntry.getValue();
			Iterator<String> listIterator = fileList.iterator();
			while (listIterator.hasNext()) {
				String fileName = listIterator.next();
				stream.println("     " + fileName); //$NON-NLS-1$
			}
		}
	}

	/**
	 * Handle an induvidual file at a time
	 *
	 *  <p>Functions:
	 *  <ul>
	 *  - <li> get user defined default date </li>
	 *  - <li> identify if multiple comments inserted. </li>
	 *    <li> update existing comment or insert a new one </li>
	 *  </ul>
	 * @param file     - file to be proccessed (.java, .bat, .xml etc...)
	 * @param adapter
	 * @param monitor
	 */
	private void processFile(IFile file, RepositoryProviderCopyrightAdapter adapter, IProgressMonitor monitor) {

		//Missign file Extension 
		if (! checkFileExtension(file)) {
		    return;
		}

		//Create an instance of the appropriate Source container. (xml/java/bash etc..)
		SourceFile aSourceFile = SourceFile.createFor(file);
		if (! checkSourceCreatedOk(aSourceFile, file)) {
		    return;
		}
		
		//Aquire user settings
		IPreferenceStore prefStore = RelEngPlugin.getDefault().getPreferenceStore();
		
		//Check if user wants to skip over this file
		if (! checkUserFileIgnoreSettings(prefStore, aSourceFile)) {
		    return;
		}

		//Skip over source files that have multiple copy-right notes 
		if (! checkMultipleCopyright(file, aSourceFile)) {
		    return;
		}

		//Extract 'current' 'raw' comment from the document.
		BlockComment copyrightComment = aSourceFile.getFirstCopyrightComment();

		
		CopyrightComment ibmCopyright = null;
		
		// if replacing all comments, don't even parse, just use default copyright comment
		if (prefStore.getBoolean(RelEngCopyrightConstants.REPLACE_ALL_EXISTING_KEY)) {
		    
		        //Aquire user default comments from settings.
			ibmCopyright = AdvancedCopyrightComment.defaultComment(aSourceFile.getFileType());
		} else {
		    
		        //Parse the raw comment and update the last revision year. (inserting a revision year if neccessary). 
			ibmCopyright = AdvancedCopyrightComment.parse(copyrightComment, aSourceFile.getFileType());  
			
			//Check that the newly created comment was constructed correctly. 
			if (ibmCopyright == null) {
			    
			        //Check against a standard IBM copyright header.
				//Let's see if the file is EPL
				ibmCopyright = IBMCopyrightComment.parse(copyrightComment, aSourceFile.getFileType());
				if (ibmCopyright != null) {
				        //Could not proccess file at all. 
					warn(file, copyrightComment, Messages.getString("AdvancedFixCopyrightAction.15")); //$NON-NLS-1$
				}
			}
		}

		//Could not determine the 'new' 'copyright' header. Do not procces file. 
		if (ibmCopyright == null) {
			warn(file, copyrightComment, Messages.getString("AdvancedFixCopyrightAction.16")); //$NON-NLS-1$
			return;
		}

		ibmCopyright.setLineDelimiter(aSourceFile.getLineDelimiter());

		// year last revised as listed in the copyright header. 
		int revised = ibmCopyright.getRevisionYear();
		
		//lasdMod = last touched by user. (e.g as defined 'default' in options). 
 		int lastMod = revised;

 		//Read user defined year from options.
		if (prefStore.getBoolean(RelEngCopyrightConstants.USE_DEFAULT_REVISION_YEAR_KEY) || adapter == null)
			lastMod = prefStore.getInt(RelEngCopyrightConstants.REVISION_YEAR_KEY);
		else {
			// figure out if the comment should be updated by comparing the date range
			// in the comment to the last modification time provided by adapter
			if (lastMod < currentYear) {
				try {
					lastMod = adapter.getLastModifiedYear(file, SubMonitor.convert(monitor, 1));
				} catch (CoreException e) {
					// Let's log the exception and continue
					RelEngPlugin
					.log(IStatus.ERROR,
							NLS.bind(
									Messages.getString("AdvancedFixCopyrightAction.17"), file.getFullPath()), e); //$NON-NLS-1$
				}
				if (lastMod > currentYear) {
					// Don't allow future years to be used in the copyright
					lastMod = currentYear;
				}
				if (lastMod == 0) {
					warn(file, copyrightComment, Messages.getString("AdvancedFixCopyrightAction.18")); //$NON-NLS-1$
					return;
				}
				// use default revision year
				if (lastMod == -1) {
					lastMod = prefStore.getInt(RelEngCopyrightConstants.REVISION_YEAR_KEY);
				}
				if (lastMod < revised) {
					// Don't let the copyright date go backwards
					lastMod = revised;
				}
			}
		}

		// only exit if existing copyright comment already contains the year
		// of last modification and not overwriting all comments
		if (lastMod <= revised && (copyrightComment != null) && (!prefStore.getBoolean(RelEngCopyrightConstants.REPLACE_ALL_EXISTING_KEY)))
			return;

		// either replace old copyright or put the new one at the top of the file
		ibmCopyright.setRevisionYear(lastMod);
		if (copyrightComment == null)   //do this on files without comments
			aSourceFile.insert(ibmCopyright.getCopyrightComment());
		else {                          //do this with files that have a copy-right comment already.

		        //Verify that the comment is at the top of the file. Warn otherwise.
		        //[276257] XML file is a special case because it can have an xml-header and other headers, thus it can start at an arbirary position.
			if (!copyrightComment.atTop() && (aSourceFile.getFileType() != CopyrightComment.XML_COMMENT)) {
				warn(file, copyrightComment, Messages.getString("AdvancedFixCopyrightAction.19")); //$NON-NLS-1$
			}
			aSourceFile.replace(copyrightComment, ibmCopyright.getCopyrightComment());
		}
	}

    private boolean checkFileExtension(IFile file) {
        if (file.getFileExtension() == null) {
            warn(file, null, Messages.getString("AdvancedFixCopyrightAction.13")); //$NON-NLS-1$
            return false;
        } else {
            return true;
        }
    }
    
    private boolean checkSourceCreatedOk(SourceFile sourceFile, IFile file) {
        if (sourceFile == null) {
            //Warn if source creation failed. 
            warn(file, null, Messages.getString("AdvancedFixCopyrightAction.20")); //$NON-NLS-1$
            return false;
        } else {
            return true;
        }
        
    }
    
	
    /**
     * Check if user chose to skip files of this kind. 
     * 
     * @param prefStore    Copyright preference store 
     * @param aSourceFile  Instance of the file to be checked. 
     * @return             false if user wishes to skip over the file. 
     */
    private boolean checkUserFileIgnoreSettings(IPreferenceStore prefStore, SourceFile aSourceFile) {

        // -- Skip file if it's a property file and user chose to ignore property files.
        if (aSourceFile.getFileType() == CopyrightComment.PROPERTIES_COMMENT
                && prefStore.getBoolean(RelEngCopyrightConstants.IGNORE_PROPERTIES_KEY)) {
            return false;
        }
        // -- Skip over xml file if the user selected to skip xml files.
        if (aSourceFile.getFileType() == CopyrightComment.XML_COMMENT
                && prefStore.getBoolean(RelEngCopyrightConstants.IGNORE_XML_KEY)) {
            return false;
        }
        return true;
    }
    
    /**
     * Check if the file has multiple copyright notices. Skip such files.
     * 
     * @param file
     * @param aSourceFile
     * @return true if it has a single notice. 
     */
    private boolean checkMultipleCopyright(IFile file, SourceFile aSourceFile) {
        if (aSourceFile.hasMultipleCopyrights()) {
            warn(file, null, Messages.getString("AdvancedFixCopyrightAction.14")); //$NON-NLS-1$
            return false;
        } else {
            return true;
        }
    }
	

	private void warn(IFile file, BlockComment firstBlockComment,
			String errorDescription) {
		List<String> aList = log.get(errorDescription);
		if (aList == null) {
			aList = new ArrayList<String>();
			log.put(errorDescription, aList);
		}
		aList.add(file.getFullPath().toString());
	}

	/**
	 * @see IActionDelegate#selectionChanged(IAction, ISelection)
	 */
	public void selectionChanged(IAction action, ISelection selection) {
		if (selection instanceof IStructuredSelection) {
			this.selection = (IStructuredSelection) selection;
		}
	}

}
