/*
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package f;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertNotNull;
import static org.hamcrest.MatcherAssert.assertThat;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.royale.compiler.clients.COMPC;
import org.apache.royale.compiler.problems.ICompilerProblem;
import org.apache.royale.utils.EnvProperties;
import org.junit.Before;
import org.junit.Test;

import com.google.common.collect.ObjectArrays;


/**
 * JUnit tests to compile the SWCs of the Flex SDK.
 * <p>
 * The projects to compile are in the <code>frameworks/projects</code> directory
 * referenced by the <code>FLEX_HOME</code> environment variable.
 * Each project has a config file which the <code>COMPC</code> uses to compile the SWC.
 * 
 * @author Gordon Smith
 */
public class SDKSWCTests
{
	private static EnvProperties env = EnvProperties.initiate();
	
	private static final String TEXTLAYOUT_NAME = "textLayout";
	private static final String MOBILETHEME_NAME = "mobiletheme";
	
	private String[] extraArgs = new String[]{}; 

	private boolean isWindowsOrMac = true;
	
	private void compileSWC(String projectName)
	{
		// Construct a command line which simply loads the project's config file.
		assertNotNull("FLEX_HOME not set in unittest.properties", env.SDK);
		assertNotNull("PLAYERGLOBAL_HOME not set in unittest.properties", env.FPSDK);
		assertNotNull("AIR_HOME not set in unittest.properties", env.AIRSDK);
        assertNotNull("TLF_HOME not set in unittest.properties", env.TLF);
		
		System.setProperty("royalelib", env.SDK + "/frameworks");
		
		String output = null;
		String outputSwcName = projectName;
		try
		{
			if(outputSwcName.length() < 3)
				outputSwcName = "_" + outputSwcName;
			File tmpFile = File.createTempFile(outputSwcName, ".swc");
			tmpFile.deleteOnExit();
			output = tmpFile.getAbsolutePath();
		}
		catch (IOException e)
		{
		}

		String configFile;
		if (projectName.equals(MOBILETHEME_NAME) && !isWindowsOrMac)
		{
			configFile = env.SDK + "/frameworks/projects/" + projectName + "/compile-configAIR2.xml";
		}
		else if (projectName.equals(TEXTLAYOUT_NAME))
		{
			configFile = env.TLF + "/compile-config.xml";
		}
		else
		{
			configFile = env.SDK + "/frameworks/projects/" + projectName + "/compile-config.xml";
		}
		
		String[] baseArgs = new String[]
		{
			"-load-config+=" + configFile,
			"+env.PLAYERGLOBAL_HOME=" + env.FPSDK,
			"+playerglobal.version=" + env.FPVER,
			"-output=" + output
		};
		
		String [] allArgs = ObjectArrays.concat(baseArgs, extraArgs, String.class);
		
		// Run the COMPC client with the specified command line.
		COMPC compc = new COMPC();
		compc.mainNoExit(allArgs);
		
		// Check that the SWC compiled cleanly.
		List<ICompilerProblem> problems = new ArrayList<ICompilerProblem>();
		for (ICompilerProblem problem : compc.getProblems().getFilteredProblems())
		{
			problems.add(problem);
		}
		assertThat(problems.size(), is(0));
	}

	@Before
	public void setUp()
	{
		String osName = System.getProperty("os.name").toLowerCase();
		isWindowsOrMac = osName.contains("windows") || osName.contains("mac os");
	}
	
	@Test
	public void advancedgridsSWC()
	{
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };

		compileSWC("advancedgrids");
	}
	
	@Test
	public void airframeworkSWC()
	{
        extraArgs = new String[]
        {
            "+env.AIR_HOME=" + env.AIRSDK,
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
        
		compileSWC("airframework");
	}
	
	@Test
	public void airsparkSWC()
	{
        extraArgs = new String[]
        {
            "+env.AIR_HOME=" + env.AIRSDK,
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
        
		compileSWC("airspark");
	}
	
	@Test
	public void apacheSWC()
	{
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
		compileSWC("apache");
	}
	
	@Test
	public void authoringsupportSWC()
	{
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
		compileSWC("authoringsupport");
	}
	
	@Test
	public void automationSWC()
	{
		if (!isWindowsOrMac)
		{
			// this doesn't get built on Linux
			return;
		}
 
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
		compileSWC("automation");
	}
	
	@Test
	public void automation_agentSWC()
	{
		if (!isWindowsOrMac)
		{
			// this doesn't get built on Linux
			return;
		}
 
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.DuplicateQNameInSourcePathProblem",
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
        
		compileSWC("automation_agent");
	}
	
	@Test
	public void automation_airsparkSWC()
	{
		if (!isWindowsOrMac)
		{
			// this doesn't get built on Linux
			return;
		}

		extraArgs = new String[]
        {
            "+env.AIR_HOME=" + env.AIRSDK,
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
        
		compileSWC("automation_airspark");
	}
	
    @Test
    public void automation_airSWC()
    {
		if (!isWindowsOrMac)
		{
			// this doesn't get built on Linux
			return;
		}

		extraArgs = new String[]
        {
            "+env.AIR_HOME=" + env.AIRSDK,
            "-ignore-problems+=org.apache.royale.compiler.problems.DuplicateQNameInSourcePathProblem",
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
        
        compileSWC("automation_air");
    }
    
	@Test
	public void automation_dmvSWC()
	{
		if (!isWindowsOrMac)
		{
			// this doesn't get built on Linux
			return;
		}

        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.DuplicateQNameInSourcePathProblem",
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
        
		compileSWC("automation_dmv");
	}
	
	@Test
	public void automation_flashflexkitSWC()
	{
		if (!isWindowsOrMac)
		{
			// this doesn't get built on Linux
			return;
		}
 
		extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
		compileSWC("automation_flashflexkit");
	}
	
	@Test
	public void automation_sparkSWC()
	{
		if (!isWindowsOrMac)
		{
			// this doesn't get built on Linux
			return;
		}
 
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
		compileSWC("automation_spark");
	}
	
	@Test
	public void chartsSWC()
	{
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
            "-locale=",
        };
        
		compileSWC("charts");
	}
	
    @Test
    public void coreSWC()
    {
        extraArgs = new String[]
        {
            "-load-config+=" + env.SDK + "/frameworks/projects/framework/framework-config.xml",
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
        
        compileSWC("core");
    }
    
    @Test
    public void mxSWC()
    {
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
            "-locale="
        };
        
        compileSWC("mx");
    }
    
    @Test
    public void experimentalSWC() // WARNINGS -> FLEX-33731
    {
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.DuplicateSkinStateProblem",
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
        
        compileSWC("experimental");
    }
    
	@Test
	public void flash_integrationSWC()
	{
		if (!isWindowsOrMac)
		{
			// this doesn't get built on Linux
			return;
		}
 
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
		compileSWC("flash-integration");
	}
	
	@Test
	public void frameworkSWC()
	{
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
            "-load-config+=" + env.SDK + "/frameworks/projects/framework/framework-config.xml"
        };
        
		compileSWC("framework");
	}
	
	@Test
	public void haloSWC()
	{
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
		compileSWC("halo");
	}
	
	@Test
	public void mobilecomponentsSWC()
	{
        extraArgs = new String[]
        {
            "+env.AIR_HOME=" + env.AIRSDK,
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
        
		compileSWC("mobilecomponents");
	}
	
	@Test
	public void mobilethemeSWC() // WARNINGS -> FLEX-33305
	{
        extraArgs = new String[]
        {
             "-ignore-problems+=org.apache.royale.compiler.problems.NoDefinitionForSWCDependencyProblem",
			 "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
        
		compileSWC("mobiletheme");
	}
	
	/*
	erikdebruin: the playerglobal project doesn't contain source that needs to
	             be compiled with COMPC

	@Test
	public void playerglobalSWC()
	{
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
		compileSWC("playerglobal");
	}
	*/
	
	@Test
	public void rpcSWC()
	{
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
		compileSWC("rpc");
	}
	
	@Test
	public void spark_dmvSWC()
	{
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
		compileSWC("spark_dmv");
	}
	
	@Test
	public void sparkskinsSWC()
	{
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
		compileSWC("sparkskins");
	}
	
	@Test
    public void sparkSWC()
    {
		// TODO: DuplicateClassDefinitionProblem is actually an error
		// the duplicate class is a generated embed class with a name that
		// starts with: framework_swc/Assets_swf$
		// the source path and containing file path are both equal.
		// either the SWC defines the same type twice, or there's a bug in the
		// compiler code that is loading the same SWC twice.
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.DuplicateSkinStateProblem",
			"-ignore-problems+=org.apache.royale.compiler.problems.NullUsedWhereOtherExpectedProblem",
			"-ignore-problems+=org.apache.royale.compiler.problems.NonBooleanUsedWhereBooleanExpectedProblem",
			"-ignore-problems+=org.apache.royale.compiler.problems.DuplicateClassDefinitionProblem",
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };

        compileSWC("spark");
    }
    
	@Test
	public void textLayoutSWC()
	{
        extraArgs = new String[]
        {
            "+source.dir=./textLayout",
            "-define=CONFIG::debug,false",
            "-define=CONFIG::release,true",
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
	            
        compileSWC(TEXTLAYOUT_NAME);
	}

    @Test
    public void tool_airSWC()
    {
		if (!isWindowsOrMac)
		{
			// this doesn't get built on Linux
			return;
		}
 
        extraArgs = new String[]
        {
            "+env.AIR_HOME=" + env.AIRSDK,
            "-ignore-problems+=org.apache.royale.compiler.problems.DuplicateQNameInSourcePathProblem",
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
        
        compileSWC("tool_air");
    }
	
	@Test
	public void toolSWC()
	{
		if (!isWindowsOrMac)
		{
			// this doesn't get built on Linux
			return;
		}
 
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.DuplicateQNameInSourcePathProblem",
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
        
		compileSWC("tool");
	}	
	
	@Test
	public void wireframeSWC() // WARNINGS -> FLEX-33310
	{
        extraArgs = new String[]
        {
            "-ignore-problems+=org.apache.royale.compiler.problems.DuplicateSkinStateProblem",
            "-ignore-problems+=org.apache.royale.compiler.problems.ThisUsedInClosureProblem",
        };
        
		compileSWC("wireframe");
	}

}
