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