/*
 * Copyright 2013 Andrew Everitt, Andrew Heckford, Daniele Masato
 *
 * Licensed 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 uk.org.raje.maven.plugin.msbuild.parser;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;

import org.junit.Test;
import org.junit.Assert;

/**
 * Test CppCheckMojo configuration options.
 */
public class VCSolutionParserTest
{
    @Test
    public void testSinglePlatformSingleConfig()
    {
        testSingleProjectSolution( TEST_PLATFORMS[0], TEST_CONFIGURATIONS[0] );
    }

    @Test
    public void testSinglePlatformMultipleConfig()
    {
        for ( String configuration : TEST_CONFIGURATIONS )
        {
            testSingleProjectSolution( TEST_PLATFORMS[0], configuration );
        }
    }

    @Test
    public void testMultiplePlatformSingleConfig()
    {
        for ( String platform : TEST_PLATFORMS )
        {
            testSingleProjectSolution( platform, TEST_CONFIGURATIONS[0] );
        }
    }
    
    @Test
    public void testMultipleProjects()
    {
        for ( String platform : TEST_PLATFORMS )
        {
            for ( String configuration : TEST_CONFIGURATIONS )
            {
                testMultipleProjectSolution( platform, configuration );
            }
        }
    }
    
    private void testSingleProjectSolution( String platform, String configuration )
    {
        String solutionPath = TEST_RESOURCE_DIR + "hello-world-solution/hello-world.sln";
        File solutionFile = new File( this.getClass().getResource( solutionPath ).getPath() );
        List<VCProject> vcProjects = parseSolution( solutionFile, platform, configuration ); 

        Assert.assertEquals( 1, vcProjects.size() );
        validateProject( vcProjects.get( 0 ), TEST_PROJECT_NAMES[0], platform, configuration );
    }
    
    private void testMultipleProjectSolution( String platform, String configuration )
    {
        String solutionPath = TEST_RESOURCE_DIR + "hello-goodbye-world-solution/hello-goodbye-world.sln";
        File solutionFile = new File( this.getClass().getResource( solutionPath ).getPath() );
        List<VCProject> vcProjects = parseSolution( solutionFile, platform, configuration );
        Assert.assertEquals( TEST_PROJECT_NAMES.length, vcProjects.size() );
        
        for ( int i = 0; i < TEST_PROJECT_NAMES.length; i++ ) 
        {
            validateProject( vcProjects.get( i ), TEST_PROJECT_NAMES[i], platform, configuration );
        }
    }

    private List<VCProject> parseSolution( File solutionFile, String platform, String configuration )
    {
        VCSolutionParser solutionParser = null;
        
        try 
        {
            solutionParser = new VCSolutionParser( solutionFile, platform, configuration );
        } 
        catch ( FileNotFoundException fnfe ) 
        {
            Assert.fail( fnfe.getMessage() );
        }
        
        try 
        {
            solutionParser.parse();
        } 
        catch ( IOException ioe ) 
        {
            Assert.fail( ioe.getMessage() );
        }
        catch ( ParseException pe ) 
        {
            Assert.fail( pe.getMessage() );
        }
        
        return solutionParser.getVCProjects();
    }
    
    private void validateProject( VCProject vcProject, String name, String platform, String configuration )
    {
        Assert.assertEquals( name, vcProject.getName() );
        Assert.assertEquals( platform, vcProject.getPlatform() );
        Assert.assertEquals( configuration, vcProject.getConfiguration() );
    }
    
    private static final String TEST_RESOURCE_DIR = "/unit/cppcheck/";
    private static final String[] TEST_PROJECT_NAMES = { "hello-world", "goodbye-world" };
    private static final String[] TEST_PLATFORMS = { "Win32", "x64" };
    private static final String[] TEST_CONFIGURATIONS = { "Debug", "Release" };   
}

@@ -1549,28 +1549,24 @@
     %7D%0A    %7D%0A
-    
 %0A    @Test%0A 
@@ -1843,28 +1843,24 @@
     %7D%0A    %7D%0A
-    
 %0A    private
@@ -2215,17 +2215,16 @@
 ation );
- 
 %0A%0A      
@@ -2334,16 +2334,23 @@
 CT_NAMES
+_SINGLE
 %5B0%5D, pla
@@ -2371,36 +2371,32 @@
 ration );%0A    %7D%0A
-    
 %0A    private voi
@@ -2809,24 +2809,33 @@
 ROJECT_NAMES
+_MULTIPLE
 .length, vcP
@@ -2852,24 +2852,16 @@
 ze() );%0A
-        
 %0A       
@@ -2900,16 +2900,25 @@
 CT_NAMES
+_MULTIPLE
 .length;
@@ -2923,17 +2923,16 @@
 h; i++ )
- 
 %0A       
@@ -3002,16 +3002,25 @@
 CT_NAMES
+_MULTIPLE
 %5Bi%5D, pla
@@ -3216,24 +3216,16 @@
 = null;%0A
-        
 %0A       
@@ -3220,33 +3220,32 @@
 ll;%0A%0A        try
- 
 %0A        %7B%0A     
@@ -3332,33 +3332,32 @@
 ion );%0A        %7D
- 
 %0A        catch (
@@ -3385,17 +3385,16 @@
 n fnfe )
- 
 %0A       
@@ -3448,32 +3448,24 @@
 ;%0A        %7D%0A
-        
 %0A        try
@@ -3464,17 +3464,16 @@
      try
- 
 %0A       
@@ -3520,17 +3520,16 @@
        %7D
- 
 %0A       
@@ -3554,17 +3554,16 @@
 on ioe )
- 
 %0A       
@@ -3655,17 +3655,16 @@
 ion pe )
- 
 %0A       
@@ -3720,24 +3720,16 @@
       %7D%0A
-        
 %0A       
@@ -3766,36 +3766,32 @@
 ojects();%0A    %7D%0A
-    
 %0A    private voi
@@ -4095,20 +4095,16 @@
 ;%0A    %7D%0A
-    
 %0A    pri
@@ -4219,16 +4219,23 @@
 CT_NAMES
+_SINGLE
  = %7B %22he
@@ -4248,18 +4248,101 @@
 rld%22
-, %22goodbye
+ %7D;%0A    private static final String%5B%5D TEST_PROJECT_NAMES_MULTIPLE = %7B %22goodbye-world%22, %22hello
 -wor
@@ -4498,14 +4498,11 @@
 ease%22 %7D;
-   
 %0A%7D%0A

Fix test failure caused by sorting order of expected results.