/*******************************************************************************
 * Copyright (c) 2000, 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
 *     Martin Oberhuber (Wind River) - [235572] detect existing comments in bat files
 *     Leo Ufimtsev lufimtse@redhat.com [276257] fix xml issues.
 *******************************************************************************/
package org.eclipse.releng.tools;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.ITextFileBufferManager;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.osgi.util.NLS;


/**
 * @author droberts
 */
public abstract class SourceFile {
	
	IFile file;
	List<BlockComment> comments = new ArrayList<BlockComment>();
	StringWriter contents = new StringWriter();
	private ITextFileBufferManager textFileBufferManager;
	private String lineDelimiter;

	public static SourceFile createFor(IFile file) {
        String extension = file.getFileExtension();
        if (extension != null) {
	        extension = extension.toLowerCase();
			if (extension.equals("java")) { //$NON-NLS-1$
				return new JavaFile(file);
	        } else if (extension.equals("c") || extension.equals("h") || extension.equals("rc") || extension.equals("cc") || extension.equals("cpp")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
	            return new CFile(file);
			} else if (extension.equals("properties")) { //$NON-NLS-1$
				return new PropertiesFile(file);
	        } else if (extension.equals("sh") || extension.equals("csh") || extension.equals("mak") || extension.equals("pl") || extension.equals("tcl")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
	            return new ShellMakeFile(file);
	        } else if (extension.equals("bat")) { //$NON-NLS-1$
	            return new BatFile(file);
			} else if (extension.equals("js")) { //$NON-NLS-1$
	            return new JavaScriptFile(file);
			} else if (extension.equals("xml")) { //$NON-NLS-1$
		    //[276257] re-enable xml support.
		    return new XmlFile(file);
			}
        }
		return null;
	}
	
	public SourceFile(IFile file) {
		super();
		this.file = file;
		initialize();
	}

	/**
	 * Test if the given line marks the start of a potential Copyright comment.
	 * Can be overridden in subclasses to perform advanced detection.
	 * @param aLine a line of text to check
	 * @return <code>true</code> if the line can mark a copyright comment start.
	 * @since 3.5
	 */
	public boolean isCommentStart(String aLine) {
		return aLine.trim().startsWith(getCommentStart());
	}
	/**
	 * Test if the given line marks the end of a potential Copyright comment.
	 * Can be overridden in subclasses to perform advanced detection.
	 * @param aLine a line of text to check
	 * @param commentStartString the line which started the block comment
	 * @return <code>true</code> if the line can mark a copyright comment end.
	 * @since 3.5
	 */
	public boolean isCommentEnd(String aLine, String commentStartString) {
		return aLine.trim().endsWith(getCommentEnd());
	}
	public abstract String getCommentStart();
	public abstract String getCommentEnd();
	

	private void initialize() {
		textFileBufferManager= FileBuffers.createTextFileBufferManager();
		try {
			
			IDocument document;
			try {
			        //connect file buffer. 
		                ITextFileBuffer fileBuffer = openFileBuffer();
		                        if (fileBuffer == null)
		                                return;
			    
				document = fileBuffer.getDocument();
			} finally {
				//Close file buffer. 
                                closeFileBuffer();
			}
			
			lineDelimiter= TextUtilities.getDefaultLineDelimiter(document);
			BufferedReader aReader = new BufferedReader(new StringReader(document.get()));
			String aLine = aReader.readLine();
			String comment = ""; //$NON-NLS-1$
			BufferedWriter contentsWriter = new BufferedWriter(contents);
			int lineNumber = 0;
			int commentStart = 0;
			int commentEnd = 0;
			boolean inComment = false;
			String commentStartString = ""; //$NON-NLS-1$
			
			//Loop over the document, extract the comment.
			while (aLine != null) {
				contentsWriter.write(aLine);
				contentsWriter.newLine();
				if (!inComment && isCommentStart(aLine)) {
					// start saving comment
					inComment = true;
					commentStart = lineNumber;
					commentStartString = aLine;
				}
				
				if (inComment) {
					comment = comment + aLine + lineDelimiter;
								
					if (isCommentEnd(aLine, commentStartString) && commentStart != lineNumber) {
						// stop saving comment
						inComment = false;
						commentEnd = lineNumber;
						String commentEndString = aLine.trim();
						commentEndString = commentEndString.substring(commentEndString.length()-2);
						BlockComment aComment = new BlockComment(commentStart, commentEnd, comment.toString(), commentStartString, commentEndString);
						comments.add(aComment);
						comment = ""; //$NON-NLS-1$
						commentStart = 0;
						commentEnd = 0;
						commentStartString = ""; //$NON-NLS-1$
					}
				}
				
				aLine = aReader.readLine();
				lineNumber++;
			}
			
			aReader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @return BlockComment
	 */
	public BlockComment firstBlockComment() {
		if (comments.isEmpty()) {
			return null;
		} else {
			return comments.get(0);
		}
	}

	/**
	 * If this method is called, <b>ensure</b> that you close the file buffer after usage. <br>
	 * Otherwise you leave a memory leak. {@link #closeFileBuffer()}
	 * {@code textFileBufferManager.disconnect(file.getFullPath(), LocationKind.IFILE, null); }
	 * @return
	 */
	private ITextFileBuffer openFileBuffer() {
		try {
			textFileBufferManager.connect(file.getFullPath(), LocationKind.IFILE, null);
		} catch (CoreException e) {
			e.printStackTrace();
			return null;
		}

		ITextFileBuffer fileBuffer= textFileBufferManager.getTextFileBuffer(file.getFullPath(), LocationKind.IFILE);
		if (fileBuffer != null)
			return fileBuffer;

		System.err.println(NLS.bind(Messages.getString("SourceFile.0"), file.getFullPath())); //$NON-NLS-1$
			return null;
	}
	
	/**
	 * This should be called before ending a file operation. <br>
	 * Companion function to getFileBuffer();
	 */
	private void closeFileBuffer() {
            try {
                textFileBufferManager.disconnect(file.getFullPath(), LocationKind.IFILE, null);
            } catch (CoreException e) {
                    e.printStackTrace();
            }
	}
	
	
	/**
	 * Given the copyright comment, this method inserts it into the right place in the file.
	 *
	 * @param copyRightComment  the complete comment that will be inserted.
	 */
	public void insert(String copyRightComment) {
		try {
		        ITextFileBuffer fileBuffer= openFileBuffer();
		        if (fileBuffer == null)
		                 return;
		    
			IDocument document= fileBuffer.getDocument();
			doInsert(copyRightComment, document);
			fileBuffer.commit(null, false);
		} catch (BadLocationException e) {
			e.printStackTrace();
		} catch (CoreException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
		    closeFileBuffer();
		}
	}

	protected void doInsert(String comment, IDocument document) throws BadLocationException, CoreException, IOException {
		document.replace(0, 0, comment);
	}

	/**
	 * @return BlockComment
	 */
	public BlockComment getFirstCopyrightComment() {
		Iterator<BlockComment> anIterator = comments.iterator();
		while (anIterator.hasNext()) {
			BlockComment aComment = anIterator.next();
			if (aComment.isCopyright()) {
				return aComment;
			}
		}
		
		return null;
	}

	/**
	 * @param aCommet
	 * @param newCopyrightComment          Comment to be inserted.
	 */
	public void replace(BlockComment aComment, String newCopyrightComment) {
		
	
		try {
			ITextFileBuffer fileBuffer = openFileBuffer();
			if (fileBuffer == null)
				return;
			
			IDocument document= fileBuffer.getDocument();

			IRegion startLine= document.getLineInformation(aComment.start);
			IRegion endLine= document.getLineInformation(aComment.end + 1);
			document.replace(startLine.getOffset(), endLine.getOffset() - startLine.getOffset(), newCopyrightComment);
			
			fileBuffer.commit(null, false);
		
		} catch (BadLocationException e) {
			e.printStackTrace();
		} catch (CoreException e) {
			e.printStackTrace();
		} finally  {
		    closeFileBuffer();
			try {
			        FileBuffers.getTextFileBufferManager().disconnect(file.getFullPath(), LocationKind.IFILE, null);
			} catch (CoreException e) {
				e.printStackTrace();
				return;
			}
		}
	}

	/**
	 * @return boolean
	 */
	public boolean hasMultipleCopyrights() {
		int count = 0;
		Iterator<BlockComment> anIterator = comments.iterator();
		while (anIterator.hasNext()) {
			BlockComment aComment = anIterator.next();
			if (aComment.isCopyright()) {
				count++;
			}
			if (count > 1) {
				return true;
			}
		}
		return false;
	}

	public abstract int getFileType();
	
	/**
	 * Returns the line delimiter.
	 * 
	 * @return the line delimiter
	 * @since 3.7
	 */
	public String getLineDelimiter() {
		return lineDelimiter;
	}
}