/*******************************************************************************
 * Copyright (c) 2004, 2008 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
 *     Markus Schorn (Wind River Systems)
 *******************************************************************************/

/*
 * Created on Oct 4, 2004
 */
package org.eclipse.photran.internal.tests;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;

import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.FileManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.photran.internal.core.FProjectNature;
import org.eclipse.photran.internal.core.util.LineCol;
import org.eclipse.photran.internal.core.vpg.PhotranVPG;
import org.eclipse.rephraserengine.core.util.Spawner;

/**
 * Base class for a test case that imports files into the runtime workspace and then operates on the
 * runtime workspace.
 * <p>
 * Most refactorings are tested in this way. However, refactoring tests should generally be created
 * by subclassing {@link PhotranRefactoringTestSuiteFromMarkers}, not by subclassing this class
 * directly.
 * <p>
 * This class is based on org.eclipse.cdt.core.tests.BaseTestFramework.
 * 
 * @author aniefer
 * @author Jeff Overbey - Modified so that every test case creates a new project - Added line/column
 *         computation when importing files - Added {@link #compileAndRunFortranProgram(String...)}
 */
public abstract class PhotranWorkspaceTestCase extends PhotranTestCase {
    static protected NullProgressMonitor	monitor;
    static protected IWorkspace 			workspace;
    static protected IProject 				project;
    static protected ICProject				cproject;
    static protected FileManager 			fileManager;
	static protected boolean				indexDisabled=false;
	
	private static int n = 0;
	
    private HashMap<String, ArrayList<Integer>> lineMaps = new HashMap<String, ArrayList<Integer>>();

	static void initProject() {
		if (project != null) {
			return;
		}
        if( CCorePlugin.getDefault() != null && CCorePlugin.getDefault().getCoreModel() != null){
			//(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset();
			monitor = new NullProgressMonitor();
			
			workspace = ResourcesPlugin.getWorkspace();
			
	        try {
	            PhotranVPG.getInstance().releaseAllASTs();
	            PhotranVPG.getDatabase().clearDatabase();
	            
	            cproject = CProjectHelper.createCCProject("PhotranTestProject" + (++n), "bin", IPDOMManager.ID_NO_INDEXER); //$NON-NLS-1$ //$NON-NLS-2$
	            CProjectHelper.addNatureToProject(cproject.getProject(), FProjectNature.F_NATURE_ID, null);
	        
	            project = cproject.getProject();
	            
	            /*project.setSessionProperty(SourceIndexer.activationKey, Boolean.FALSE );
	        	//Set the id of the source indexer extension point as a session property to allow
	    		//index manager to instantiate it
	    		project.setSessionProperty(IndexManager.indexerIDKey, sourceIndexerID);*/
	    		
	 
	    		
	        } catch ( CoreException e ) {
	            /*boo*/
	        }
			if (project == null)
				fail("Unable to create project"); //$NON-NLS-1$
	
			//Create file manager
			fileManager = new FileManager();
        }
	}
            
    public PhotranWorkspaceTestCase()
    {
        super();
    }

    public PhotranWorkspaceTestCase(String name)
    {
        super(name);
    }
    
	@Override
	protected void setUp() throws Exception {
		super.setUp();
		initProject();
	}

	@Override
	protected void tearDown() throws Exception {
        if( project == null || !project.exists() )
            return;
        
//        IResource [] members = project.members();
//        for( int i = 0; i < members.length; i++ ){
//            if( members[i].getName().equals( ".project" ) || members[i].getName().equals( ".cproject" ) ) //$NON-NLS-1$ //$NON-NLS-2$
//                continue;
//            if (members[i].getName().equals(".settings"))
//            	continue;
//            try{
//                members[i].delete( false, monitor );
//            } catch( Throwable e ){
//                /*boo*/
//            }
//        }
        
        try {
            project.delete(true, true, new NullProgressMonitor());
        } catch( Throwable e ){
            /* boo */
            project.close(new NullProgressMonitor());
            // To speed things up a bit and conserve memory...
            PhotranVPG.getInstance().releaseAllASTs();
            PhotranVPG.getDatabase().clearDatabase();
        }
        project = null;
	}

    private IFile importFile(String fileName, String contents ) throws Exception{
		//Obtain file handle
		IFile file = project.getProject().getFile(fileName);
		
		InputStream stream = new ByteArrayInputStream( contents.getBytes() );
		//Create file input stream
		if( file.exists() )
		    file.setContents( stream, false, false, monitor );
		else
			file.create( stream, false, monitor );
		
		fileManager.addFile(file);
		
		return file;
	}

    /**
     * If the environment variables COMPILER and EXECUTABLE are set during the JUnit run,
     * compiles and runs the Fortran program being refactored and returns the output of
     * the compilation and execution.  Otherwise, returns the empty string.
     * <p>
     * (This is intended to allow developers creating refactorings to test their refactorings
     * by actually compiling the code, while not forcing other developers to do so, since
     * it can be time-consuming.  Tests should NOT assume that a compiler is available.)
     * <p>
     * This will compile the file(s) that are currently being refactored (i.e., the files
     * imported into the test project using {@link #importFile(Plugin, String, String)}) into a
     * single executable, and then run that executable.  This can be invoked before and
     * after a refactoring is performed to make sure runtime behavior is actually preserved
     * for the test program.  If a specific ordering of the filenames is desired, it
     * must be passed as an argument to this method; otherwise, all *.f* resources in the
     * test project will be passed to the compiler in no specific order.
     * <p>
     * COMPILER must be set to the path of your Fortran compiler, e.g.,
     * /usr/local/gfortran/bin/gfortran
     * <p>
     * EXECUTABLE gives a path for the generated executable, e.g.,
     * /Users/joverbey/fortran-test-program.exe
     * <p>
     * The actual command line that is invoked is printed to standard output.
     * <p>
     * NOTE: Occasionally, the last part of the output from the Fortran program may seem to
     * be missing.  (This may be a gfortran-specific problem.)  You should include a
     * statement to manually flush the output to ensure that your test cases always pass.
     * In gfortran, you can "CALL FLUSH" to invoke the (proprietary) flush intrinsic; or
     * there is also a FLUSH statement in Fortran 2003.
     *
     * @return the output from the compiler and executable
     * @throws Exception
     */
    protected String compileAndRunFortranProgram(String... filenamesOpt) throws Exception
    {
        String compiler = System.getenv("COMPILER");
        if (compiler == null) return "";

        String exe = System.getenv("EXECUTABLE");
        if (exe == null) return "";

        ArrayList<String> args = new ArrayList<String>(8);
        args.add(compiler);

        args.add("-falign-functions");
        
        args.add("-o");
        args.add(exe);
        if (filenamesOpt == null || filenamesOpt.length == 0)
        {
            for (IResource res : project.members())
                if (res instanceof IFile && res.getFileExtension().startsWith("f"))
                    args.add(res.getName());
        }
        else
        {
            for (String filename : filenamesOpt)
                args.add(filename);
        }

        System.out.println(toString(args));
        String output = Spawner.run(project.getLocation().toFile(), args);
        //System.out.println(output);

        System.out.println(exe);
        String output2 = Spawner.run(project.getLocation().toFile(), exe);
        //System.out.println(output2);
        
        // Wait a few milliseconds for the file lock on a.exe to be released
        // Otherwise Windows 7 + Cygwin may give a "Device or resource busy"
        // error when we compile to a.exe in the next test case
        Thread.sleep(250); // 1/4 of a second seems to be sufficient

        return output + "\n" + output2;
    }

    private String toString(ArrayList<String> args)
    {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < args.size(); i++)
            sb.append((i == 0 ? "" : " ") + args.get(i));
        return sb.toString();
    }

    protected IFile importFile(Plugin activator, String srcDir, String filename) throws Exception
    {
        //project.getProject().getFile(filename).delete(true, new NullProgressMonitor());
        IFile result = importFile(filename, readTestFile(activator, srcDir, filename));
        //project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
        return result;
    }

    protected String readTestFile(Plugin activator, String srcDir, String filename) throws IOException, URISyntaxException
    {
        ArrayList<Integer> lineMap = new ArrayList<Integer>(50);
        lineMaps.put(filename, lineMap);
        lineMap.add(0); // Offset of line 1
        URL resource = activator.getBundle().getResource(srcDir + "/" + filename);
        assertNotNull(resource);
        return readStream(lineMap, resource.openStream());
    }

    protected String readStream(InputStream inputStream) throws IOException
    {
        return readStream(null, inputStream);
    }

    private String readStream(ArrayList<Integer> lineMap, InputStream inputStream) throws IOException
    {
        StringBuffer sb = new StringBuffer(4096);
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
        for (int offset = 0, ch = in.read(); ch >= 0; ch = in.read())
        {
            sb.append((char)ch);
            offset++;

            if (ch == '\n' && lineMap != null)
            {
                //System.out.println("Line " + (lineMap.size()+1) + " starts at offset " + offset);
                lineMap.add(offset);
            }
        }
        in.close();
        return sb.toString();
    }

    protected String readWorkspaceFile(String filename) throws IOException, CoreException
    {
        return readStream(project.getFile(filename).getContents(true));
    }

    /**
     * @param filename
     * @param line line number, starting at 1
     * @param col column number, starting at 1
     */
    protected int getLineColOffset(String filename, LineCol lineCol)
    {
        return lineMaps.get(filename).get(lineCol.getLine()-1) + (lineCol.getCol()-1);
    }
}
