/*******************************************************************************
 * 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<>();
	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);
			try (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++;
				}

			}
		} 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;
	}
}