/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 * 
 * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany,
 * for its Fraunhofer Institute and Computer Architecture and Software
 * Technology (FIRST), Berlin, Germany and Technical University Berlin,
 * Germany.
 * 
 * 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
 * 
 * Please visit http://www.eclipse.org/objectteams for updates and contact.
 * 
 * Contributors:
 * 	  Fraunhofer FIRST - Initial API and implementation
 * 	  Technical University Berlin - Initial API and implementation
 **********************************************************************/
package org.eclipse.objectteams.otdt.tests;


import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceDescription;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.objectteams.otdt.core.IOTJavaElement;
import org.eclipse.objectteams.otdt.core.IOTType;
import org.eclipse.objectteams.otdt.core.IRoleType;
import org.eclipse.objectteams.otdt.core.OTModelManager;
import org.eclipse.objectteams.otdt.core.TypeHelper;
import org.eclipse.objectteams.otdt.tests.otmodel.TestDataHandler;
import org.eclipse.objectteams.otdt.tests.otmodel.TestSetting;

public abstract class FileBasedTest extends AbstractJavaModelTests
{
    private static final String LINE_SEPARATOR = System
                                                   .getProperty("line.separator");
    private static final String WORKSPACE_DIR  = "workspace";
    
    private String              _projectDir;
	protected IJavaProject      javaProject;

    public FileBasedTest(String name)
    {
        super(name);
        
        if (getTestSetting() != null)
        	setUsePerformanceMeter(false);
    }

    public TestSetting getTestSetting()
    {
        return TestDataHandler.getTestSetting(getClass());
    }
    
    public String getSourceWorkspacePath()
    {
        return getPluginDirectoryPath()
                + java.io.File.separator
                + WORKSPACE_DIR;
    }

    public void setUpSuite() throws Exception
    {
        super.setUpSuite();
        
        // ensure autobuilding is turned off
        IWorkspaceDescription description = getWorkspace().getDescription();
        if (description.isAutoBuilding())
        {
            description.setAutoBuilding(false);
            getWorkspace().setDescription(description);
        }
        if (_projectDir != null)
        	this.javaProject = setUpJavaProject(_projectDir); 
    }

    public void tearDownSuite() throws Exception
    {
        this.deleteProject(_projectDir);
        super.tearDownSuite();
    }

    /**
     * Returns the OS path to the directory that contains this plugin.
     */
    protected String getPluginDirectoryPath()
    {
        try
        {
            URL platformURL = Platform
				                .getBundle(getPluginID())
				                .getEntry("/");
            return new File(FileLocator.toFileURL(platformURL).getFile())
                .getAbsolutePath();
        }
        catch (IOException ex)
        {
            ex.printStackTrace();
        }
        return null;
    }
    
    protected abstract String getPluginID();

    protected String getResource(String packageName, String resourceName)
    {
        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();

        IResource resource = workspaceRoot.findMember(new Path("/"
                + _projectDir
                + "/"
                + packageName
                + "/"
                + resourceName));
        assertNotNull("No resource found", resource);
        return resource.getLocation().toOSString();
    }

    protected String getSource(ASTNode astNode, char[] source)
    {
        String result = new String(CharOperation.subarray(source, astNode
            .getStartPosition() + 1, astNode.getStartPosition()
                + astNode.getLength()
                - 1));
        if (result.endsWith("\\n"))
        {
            return result.substring(0, result.length() - 2) + LINE_SEPARATOR;
        }
        return result;
    }
    
    protected void setTestProjectDir(String dirName)
    {
        _projectDir = dirName;
    }
    
    protected String getTestProjectDir()
    {
        return _projectDir;
    }
    
    public boolean isRole(IType type)
    {
        IOTType otType =
            OTModelManager.getOTElement(type);
        return (otType != null)
        	&& (otType.exists())
        	&& (otType instanceof IRoleType);
    }
    
    public IRoleType getRole(String project, String srcFolder, String pkg, String aTeam, String role)
    	throws JavaModelException
	{
	    ICompilationUnit teamUnit = 
	        getCompilationUnit(project, srcFolder, pkg, aTeam + ".java"); 
	    assertNotNull(teamUnit);
	    assertTrue(teamUnit.exists());
	    
	    IType teamType = teamUnit.getType(aTeam);
	    assertNotNull(teamType);
	    assertTrue(teamType.exists());
	    
	    IType javaModelRole = teamType.getType(role);
	    assertNotNull(javaModelRole);
	    assertTrue(javaModelRole.exists());
	    
        IOTJavaElement roleType = 
            OTModelManager.getOTElement(javaModelRole);
        return (IRoleType)roleType;
	
	}
    
    public IType getRole(IType aTeam, String role)
    {
        return TypeHelper.findNestedRoleType(aTeam, role);
    }
    
    public IType getMemberType(String project, String srcFolder, String pkg, String enclosingTypeName, String member)
		throws JavaModelException
	{
	    ICompilationUnit declaringUnit = 
	        getCompilationUnit(project, srcFolder, pkg, enclosingTypeName + ".java"); 
	    assertTrue(declaringUnit.exists());
	    
	    IType enclosingType = declaringUnit.getType(enclosingTypeName);
	    assertTrue(enclosingType.exists());
	    
	    IType memberType = enclosingType.getType(member);
	    assertTrue(memberType.exists());
	
	    return memberType;
	}
    
    public IType getType(String projectName, String srcFolder, String pkg, String typeName)
    	throws JavaModelException
	{
	    ICompilationUnit declaringUnit = 
	        getCompilationUnit(projectName, srcFolder, pkg, typeName + ".java"); 
	    
	    IType type = declaringUnit != null ? declaringUnit.getType(typeName) : null;
	    if(type == null)
	    {
		    type = getJavaProject(projectName).findType(pkg + "." + typeName);
	    }
	    assertNotNull(type);
	    assertTrue(type.exists());
	    
	    return type;
	}

    
    public IType getRoleJavaElem(
            String project, 
            String srcFolder, 
            String pkg, 
            String aTeam, 
            String role)
    	throws JavaModelException
    {
        return getMemberType(
                project, 
                srcFolder,
                pkg,
                aTeam,
                role);
    }
    
    public boolean containsAllRequiredTypes(IType[] actual, List expected)
    {
        if(actual == null 
            || expected == null
            || actual.length != expected.size())
        {
            return false;
        }
        boolean result = true;
        Iterator iterator = expected.iterator();
        while(iterator.hasNext())
        {
            String currentExpected = (String)iterator.next();
            //Is currentExpected contained in actual
            boolean loopResult = false;
	        for(int actualIdx = 0; actualIdx < actual.length; actualIdx++)
	        {
	            loopResult |= currentExpected.compareTo(actual[actualIdx].getFullyQualifiedName()) == 0;
	            if(loopResult)
	            {
	                break;
	            }
	        }
	        result &= loopResult;
        }
        return result;
    }
    
    
    /**
     * Fully qualified name-based comparison of typelists, without respect to the order
     * @param expected types that have been expected
     * @param actual types that are actually there
     */
    public boolean compareTypes(IType[] expected, IType[] actual)
    {
        if(actual == null 
                || expected == null
                || actual.length != expected.length)
        {
        	System.out.println("Length mismatch: expected "+(expected == null ? "null" : expected.length)+
        						" but got "+(actual == null ? "null" : actual.length));
            return false;
        }
        
        boolean result = true;
        for (int expIdx = 0; expIdx < expected.length; expIdx++)
        {
            String curExpName = expected[expIdx].getFullyQualifiedName();
            //Is currentExpected contained in actual
            boolean loopResult = false;
	        for (int actIdx = 0; actIdx < actual.length; actIdx++)
	        {
	            loopResult |= curExpName.compareTo(actual[actIdx].getFullyQualifiedName()) == 0;
	            if (loopResult)
	            {
	                break;
	            }
	        }
	        if (!loopResult)
	        	System.out.println("Not found: "+curExpName);
	        result &= loopResult;
        }
        return result;
    }
    
    /**
     * Name-based comparison of methodlists, without respect to the order
     * @param expected methods that have been expected
     * @param actual methods that are actually there
     */
    public boolean compareMethods(IMethod[] expected, IMethod[] actual)
    {
        if(actual == null 
                || expected == null
                || actual.length != expected.length)
        {
            return false;
        }
        
        boolean result = true;
        for (int expIdx = 0; expIdx < expected.length; expIdx++)
        {
            String curExpName = expected[expIdx].toString();
            //Is currentExpected contained in actual
            boolean loopResult = false;
            for (int actIdx = 0; actIdx < actual.length; actIdx++)
            {
                loopResult |= curExpName.compareTo(actual[actIdx].toString()) == 0;
                if (loopResult)
                {
                    break;
                }
            }
            result &= loopResult;
        }
        return result;
    }
    
    /**
     * Fully qualified name-based comparison of two types
     */
    public boolean compareTypes(IType type1, IType type2)
    {
        if (type1 == null || type2 == null)
        {
            return false;
        }
        
        String name1 = type1.getFullyQualifiedName();
        String name2 = type2.getFullyQualifiedName();
        
        return name1.equals(name2);
    }

    public IType getJavaLangObject(IJavaProject project) throws JavaModelException
    {
        IType jlo = project.findType("java.lang.Object");
        assertTrue(jlo != null);
        assertTrue(jlo.exists());
        return jlo;
    }
    
// Println output disabled
//	/**
//	 * enriches the super-method with print-statements
//	 */
//	public void runBare() throws Throwable 
//	{
//	    System.out.println("\nsetUp");
//		setUp();
//		try {
//		    System.out.println("\n" +getName());
//			runTest();
//		}
//		finally {
//			tearDown();
//		}
//	}    
}