package npanday.its;

/*
 * 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.
 */

import junit.framework.TestCase;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.it.VerificationException;
import org.apache.maven.it.Verifier;
import org.apache.maven.it.util.FileUtils;
import org.apache.maven.it.util.ResourceExtractor;
import org.apache.maven.it.util.cli.CommandLineException;
import org.apache.maven.it.util.cli.CommandLineUtils;
import org.apache.maven.it.util.cli.Commandline;
import org.apache.maven.it.util.cli.StreamConsumer;
import org.apache.maven.it.util.cli.WriterStreamConsumer;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipFile;

public abstract class AbstractNPandayIntegrationTestCase
    extends TestCase
{
    protected boolean skip;

    protected String skipReason;

    private static final String NPANDAY_MAX_FRAMEWORK_VERSION_PROPERTY = "npanday.framework.version";

    private static final String NPANDAY_VERSION_SYSTEM_PROPERTY = "npanday.version";

    protected static DefaultArtifactVersion version = checkVersion();

    private static DefaultArtifactVersion frameworkVersion = checkFrameworkVersion();

    private static boolean debugMaven = Boolean.valueOf( System.getProperty( "debug.maven", "false" ) );

    private static boolean debugOutput = Boolean.valueOf( System.getProperty( "npanday.log.debug", "false" ) );

    private static boolean forceVersion = Boolean.valueOf( System.getProperty( "npanday.version.force", "false" ) );

    private static final Pattern PATTERN = Pattern.compile( "(.*?)-(RC[0-9]+|SNAPSHOT)" );

    private static String disasmArg;

    private static String disasmExec;

    protected AbstractNPandayIntegrationTestCase()
    {
        this( "(0,)" );
    }

    protected AbstractNPandayIntegrationTestCase( String versionRangeStr )
    {
        VersionRange versionRange = createVersionRange(versionRangeStr);

        if ( !checkNPandayVersion( versionRange, version ) && !forceVersion )
        {
            skip = true;
            skipReason = "NPanday version " + version + " not in range " + versionRange;
        }
    }

    protected static boolean checkNPandayVersion( VersionRange versionRange, DefaultArtifactVersion version )
    {
        String v = version.toString();

        Matcher m = PATTERN.matcher(v);
        if ( m.matches() )
        {
            return versionRange.containsVersion( new DefaultArtifactVersion( m.group( 1 ) ) );
        }
        else
        {
            return versionRange.containsVersion( version );
        }
    }

    protected AbstractNPandayIntegrationTestCase( String versionRangeStr, String frameworkVersionStr )
    {
        this( versionRangeStr );

        VersionRange versionRange = createVersionRange(frameworkVersionStr);

        if ( frameworkVersion != null && !versionRange.containsVersion( frameworkVersion ) && !forceVersion )
        {
            skip = true;
            skipReason = "Framework version " + frameworkVersion + " not in range " + versionRange;
        }
    }

    private static DefaultArtifactVersion checkVersion()
    {
        DefaultArtifactVersion version = null;
        String v = System.getProperty( NPANDAY_VERSION_SYSTEM_PROPERTY );
        if ( v != null )
        {
            version = new DefaultArtifactVersion( v );
            System.out.println( "Using NPanday version " + version );
        }
        else
        {
            System.out.println( "No NPanday version given" );
        }
        return version;
    }

    private static DefaultArtifactVersion checkFrameworkVersion()
    {
        DefaultArtifactVersion version = null;
        String v = System.getProperty( NPANDAY_MAX_FRAMEWORK_VERSION_PROPERTY );
        if ( v != null )
        {
            version = new DefaultArtifactVersion( v );
            System.out.println( "Using Framework versions <= " + version );
        }
        else
        {
            // TODO: this is not necessarily accurate. While it gets all those available, the max should actually be
            //       the one in the path (which can be obtained from the output for csc, but there may be other better
            //       ways such as a small C# app to interrogate it.
            //       It may be best to have an NPanday plugin that can reveal it then call that first to set it,
            //       reusing the vendor info

            File versions = new File( System.getenv( "systemroot" ) + "\\Microsoft.NET\\Framework" );
            if ( versions.exists() )
            {
                List<DefaultArtifactVersion> frameworkVersions = new ArrayList<DefaultArtifactVersion>();
                String[] list = versions.list( new java.io.FilenameFilter()
                {
                    public boolean accept( File parent, String name )
                    {
                        File f = new File( parent, name );
                        // Mscorlib.dll can be used to detect 2.0 SDK, Microsoft.CompactFramework.Build.Tasks.dll for 3.5 SDK
                        // Having just the runtime (without these files) is not sufficient
                        return f.isDirectory() && ( new File( f, "Mscorlib.dll" ).exists() || new File( f,
                                                                                                        "Microsoft.CompactFramework.Build.Tasks.dll" ).exists() );
                    }
                } );
                if ( list != null && list.length > 0 )
                {
                    for ( String frameworkVersion : list )
                    {
                        frameworkVersions.add( new DefaultArtifactVersion( frameworkVersion ) );
                    }
                    Collections.sort( frameworkVersions );
                    System.out.println( "Available framework versions: " + frameworkVersions );
                    version = frameworkVersions.get( frameworkVersions.size() - 1 );
                    System.out.println( "Selected framework version: " + version );
                }
            }
            if ( version == null )
            {
                System.out.println( "No Framework version given - attempting to use all" );
            }
        }
        return version;
    }

    protected static VersionRange createVersionRange( String versionRangeStr )
    {
        VersionRange versionRange;
        try
        {
            versionRange = VersionRange.createFromVersionSpec( versionRangeStr );
        }
        catch ( InvalidVersionSpecificationException e )
        {
            throw new RuntimeException( "Invalid version range: " + versionRangeStr + " - " + e.getMessage(), e );
        }
        return versionRange;
    }

    protected static void assertZipEntries( File zipFile, List<String> expectedEntries )
        throws IOException
    {
        assertZipEntries( zipFile, expectedEntries, true );
    }

    protected static void assertNoZipEntries( File zipFile, List<String> unexpectedEntries )
        throws IOException
    {
        assertZipEntries( zipFile, unexpectedEntries, false );
    }

    protected static void assertZipEntries( File zipFile, List<String> expectedEntries, boolean expected )
        throws IOException
    {
        ZipFile zip = new ZipFile( zipFile );
        try
        {
            for ( String name : expectedEntries )
            {
                if ( expected )
                {
                    assertNotNull( "expected " + name + " to be present in zip", zip.getEntry( name ) );
                }
                else
                {
                    assertNull( "expected " + name + " to be absent in zip", zip.getEntry( name ) );
                }
            }
        }
        finally
        {
            zip.close();
        }
    }

    protected static String translateMsDeployPath( String basedir, String path )
    {
        String p = new File( new File( basedir, "target/packages" ), path ).getAbsolutePath();
        p = p.replace( '\\', '/' );
        p = "Content/C_C" + p.substring( 2 ); // transform C:
        // Note: above is an assumption for where you can run these tests - not sure how other drive letters transformed
        // by Web Deploy
        return p;
    }

    protected void runTest()
        throws Throwable
    {
        System.out.println();
        System.out.print( String.format("%1$-70s", getITName() + "." + getName()));

        if ( skip )
        {
            System.out.print( " Skipping (" + skipReason + ")" );
            return;
        }

        try
        {
            super.runTest();
            System.out.print( "OK" );
        }
        catch ( Throwable t )
        {
            // TODO: this actually never happens on my machine. me@lcorneliussen.de
            System.out.print( "FAILURE" );
            throw t;
        }
    }

    private String getITName()
    {
        String simpleName = getClass().getSimpleName();
        simpleName = simpleName.endsWith( "Test" ) ? simpleName.substring( 0, simpleName.length() - 4 ) : simpleName;
        return simpleName;
    }

    protected Verifier getVerifier( File testDirectory )
        throws VerificationException
    {
        Verifier verifier;
        if ( debugMaven )
        {
            verifier = new Verifier( testDirectory.getAbsolutePath() ) {
                public String getExecutable() { return super.getExecutable() + "Debug"; }
            };
        }
        else
        {
            verifier = new Verifier( testDirectory.getAbsolutePath() );
        }
        List<String> cliOptions = new ArrayList<String>( 2 );
        cliOptions.add( "-Dnpanday.version=" + version );
        cliOptions.add( "-Dnpanday.settings=" + new File( testDirectory, "npanday-settings.xml" ).getAbsolutePath() );
        if ( debugOutput )
        {
            cliOptions.add( "-X" );
        }
        verifier.setCliOptions( cliOptions );
        return verifier;
    }

    protected String getCommentsFile()
    {
        return "target/comments.xml";
    }

    protected String getBuildSourcesGenerated( String fileName )
    {
        return getBuildFile("build-sources", fileName);
    }

    protected String getBuildFile( String buildDirectory, String fileName )
    {
        return "target/" + buildDirectory + "/" + fileName;
    }

    protected String getAssemblyFile( String assemblyName, String type )
    {
        return getAssemblyFile(assemblyName, null, type, null);
    }

    protected String getAssemblyFile( String assemblyName, String version, String type )
    {
        return getAssemblyFile(assemblyName, version, type, null);
    }

    protected String getAssemblyFile( String assemblyName, String version, String type, String classifier )
    {
        return getAssemblyFilePath( "target", assemblyName, type );
    }

    protected void clearRdfCache()
        throws IOException
    {
        FileUtils.deleteDirectory(new File(System.getProperty("user.home"), ".m2/uac/rdfRepository"));
    }

    protected void deleteArtifact( Verifier verifier, String groupId, String artifactId, String version, String type )
        throws IOException
    {
        FileUtils.deleteDirectory( new File( System.getProperty( "user.home" ), ".m2/uac/gac_msil/" + artifactId + "/" + version + "__" + groupId ) );
        verifier.deleteArtifact(groupId, artifactId, version, type);
    }

    protected void assertSubsystem( String assembly, int subsystem )
        throws VerificationException
    {
        assertEquals( "Subsystem was not " + subsystem + " as expected in assembly " + assembly, subsystem, getSubsystem( assembly ) );
    }

    private int getSubsystem( String assembly )
        throws VerificationException
    {
        String output = runILDisasm( assembly );

        for ( String line : output.split( "\n" ) )
        {
            line = line.trim();

            if ( line.startsWith( ".subsystem 0x" ) )
            {
                String value = line.substring( 13, line.indexOf( ' ', 13 ) );
                return Integer.parseInt( value );
            }
        }
        throw new VerificationException( "Unable to determine subsystem" );
    }

    protected void assertClassPresent( String assembly, String className )
        throws VerificationException
    {
        if ( !isClassPresent( assembly, className ) )
        {
            fail( "Unable to find class " + className + " in assembly " + assembly );
        }
    }

    protected void assertClassNotPresent( String assembly, String className )
        throws VerificationException
    {
        if ( isClassPresent( assembly, className ) )
        {
            fail( "Found unexpected class " + className + " in assembly " + assembly );
        }
    }

    private boolean isClassPresent( String assembly, String className )
        throws VerificationException
    {
        String output = runILDisasm( assembly );

        String currentClassName = className;

        int index = className.indexOf( '.' );
        String namespace = index > 0 ? className.substring( 0, index ) : "";
        for ( String line : output.split( "\n" ) )
        {
            line = line.trim();
            // mono disassembles like this instead
            if ( line.startsWith( ".namespace " + namespace ) )
            {
                currentClassName = className.substring( namespace.length() + 1 );
            }

            if ( line.startsWith( ".class " ) && line.endsWith( currentClassName ) )
            {
                return true;
            }
        }
        return false;
    }

    private String runILDisasm( String assembly )
        throws VerificationException
    {
        if ( disasmExec != null )
        {
            if ( disasmArg != null )
            {
                return execute( disasmExec, new String[]{disasmArg, assembly} );
            }
            else
            {
                return execute( disasmExec, new String[]{assembly} );
            }
        }

        String value;

        for (String path : new String[] { System.getenv("ProgramFiles"), System.getenv("ProgramFiles(x86)")}) {
            File[] versions = new File(path, "Microsoft SDKs\\Windows").listFiles();
            if (versions != null) {
                for (File f : versions) {
                    File ildasm = new File(f, "bin\\ildasm.exe");
                    if (ildasm.exists()) {
                        disasmExec = ildasm.getAbsolutePath();
                    }
                }
            }
        }
        if (disasmExec != null) {
            value = execute( disasmExec, new String[]{"/text", assembly} );
            disasmArg = "/text";
        }
        else {
            value = execute( "monodis", new String[]{assembly} );
            disasmExec = "monodis";
            disasmArg = null;
        }

        return value;
    }

    private String execute( String executable, String[] args )
        throws VerificationException
    {
        try
        {
            Commandline cli = new Commandline();
            cli.setExecutable( executable );
            for ( String arg : args )
            {
                cli.createArgument().setValue( arg );
            }

            Writer logWriter = new StringWriter();

            StreamConsumer out = new WriterStreamConsumer( logWriter );

            StreamConsumer err = new WriterStreamConsumer( logWriter );

//            System.err.println( "Command: " + Commandline.toString( cli.getCommandline() ) );

            int ret = CommandLineUtils.executeCommandLine( cli, out, err );

            logWriter.close();

            String output = logWriter.toString();
            if ( ret > 0 )
            {
                System.err.println( output );
                throw new VerificationException( "Exit code: " + ret );
            }

            return output;
        }
        catch ( CommandLineException e )
        {
            throw new VerificationException( e );
        }
        catch ( IOException e )
        {
            throw new VerificationException( e );
        }
    }

    protected String getTestAssemblyFile( String artifactId, String version, String type )
    {
        String basedir = "target/test-assemblies";
        return getAssemblyFilePath(basedir, artifactId, type);
    }

    private String getAssemblyFilePath( String basedir, String artifactId, String type )
    {
        StringBuilder sb = new StringBuilder();
        sb.append( basedir );
        sb.append( "/" );
        sb.append( artifactId );
        sb.append( "." );
        sb.append( type );
        return sb.toString();
    }

    protected String getAssemblyResourceFile( String fileName )
    {
        return getBuildFile( "assembly-resources", fileName );
    }

    protected void assertResourcePresent( String assembly, String resource )
        throws VerificationException
    {
        if ( !isResourcePresent( assembly, resource ) )
        {
            fail( "Unable to find resource " + resource + " in assembly " + assembly );
        }
    }

    protected void assertResourcePresent( String assembly, String assemblyName, String resource )
        throws VerificationException
    {
        if ( !isResourcePresent( assembly, assemblyName, resource ) )
        {
            fail( "Unable to find resource " + resource + " in assembly " + assembly );
        }
    }

    private boolean isResourcePresent( String assembly, String resource )
        throws VerificationException
    {
        return isResourcePresent(assembly, getAssemblyName(assembly), resource);
    }

    private boolean isResourcePresent( String assembly, String assemblyName, String resource )
        throws VerificationException
    {
        String output = runILDisasm( assembly );

        String prefix = ".mresource public ";
        String value = assemblyName + "." + resource.replace( '/', '.' );
        for ( String line : output.split( "\n" ) )
        {
            line = line.trim();
            if ( line.startsWith( prefix ) )
            {
                line = line.substring( prefix.length() );
                if ( line.equals( value ) || line.equals( "'" + value + "'" ) )
                {
                    return true;
                }
            }
        }
        return false;
    }

    private String getAssemblyName( String assembly )
    {
        return assembly.substring( assembly.lastIndexOf( File.separatorChar ) + 1, assembly.lastIndexOf( '.' ) );
    }

    protected void assertPublicKey( String assembly )
        throws VerificationException
    {
        if ( !hasPublicKey( assembly ) )
        {
            fail( "Couldn't find public key in assembly " + assembly );
        }
    }

    private boolean hasPublicKey( String assembly )
        throws VerificationException
    {
        String output = runILDisasm(assembly);

        boolean insideCorrectAssembly = false;
        for ( String line : output.split( "\n" ) )
        {
            if ( line.startsWith( ".assembly " + getAssemblyName( assembly ) ) )
            {
                insideCorrectAssembly = true;
            }
            else if ( line.startsWith( "}" ) )
            {
                insideCorrectAssembly = false;
            }
            else if ( insideCorrectAssembly && line.trim().startsWith( ".publickey" ) )
            {
                return true;
            }
        }
        return false;
    }

    private String getAssemblyFrameworkVersion( File assembly )
        throws VerificationException
    {
        String output = runILDisasm(assembly.getAbsolutePath());

        String prefix = "// Metadata version: v";
        for ( String line : output.split( "\n" ) )
        {
            line = line.trim();
            if ( line.startsWith( prefix ) )
            {
                return line.substring( prefix.length() ).trim();
            }
        }
        return null;
    }

    private boolean isAssemblyFrameworkVersion( File assembly, String versionRangeStr )
        throws VerificationException
    {
        String frameworkVersion = getAssemblyFrameworkVersion( assembly );
        VersionRange versionRange = createVersionRange( versionRangeStr );
        return versionRange.containsVersion( new DefaultArtifactVersion( frameworkVersion ) );
    }

    protected void assertAssemblyFrameworkVersion( File assembly, String versionRangeStr )
        throws VerificationException
    {
        String frameworkVersion = getAssemblyFrameworkVersion( assembly );
        VersionRange versionRange = createVersionRange(versionRangeStr);
        if ( !versionRange.containsVersion( new DefaultArtifactVersion( frameworkVersion ) ) )
        {
            fail( "Framework version " + frameworkVersion + " is not in range " + versionRangeStr );
        }
    }

    protected static boolean checkNPandayVersion( String versionRangeStr )
    {
        return checkNPandayVersion( createVersionRange( versionRangeStr ), version ) || forceVersion;
    }

    protected NPandayIntegrationTestContext createDefaultTestContext()
        throws IOException, VerificationException
    {
        NPandayIntegrationTestContext context = new NPandayIntegrationTestContext();

        File testDir = ResourceExtractor.simpleExtractResources( getClass(), "/" + getClass().getSimpleName() );

        context.setGroupId("NPanday.ITs." + getClass().getSimpleName());
        context.setTestDir(testDir);

        Verifier verifier = getVerifier( testDir );
        verifier.deleteArtifacts( context.getGroupId() );

        context.setVerifier(verifier);

        return context;
    }

    protected void skipIfMissingGAC( String gac, String message )
    {
        File f = new File( System.getenv( "SYSTEMROOT" ), "assembly/GAC_MSIL/" + gac );
        if ( !f.exists() || !f.isDirectory() )
        {
            skipReason = message;
            skip = true;
        }
    }

    protected void skipIfMissingProgramFilesDirectory( String directory, String message )
    {
        File f = new File( System.getenv( "PROGRAMFILES" ), directory );
        if ( !f.exists() || !f.isDirectory() )
        {
            skipReason = message;
            skip = true;
        }
    }

    protected void skipIfMissingMSBuildTask( String path, String message )
    {
        File f = new File( System.getenv( "PROGRAMFILES" ), "MSBuild" );
        f = new File( f, path );
        if ( !f.exists() )
        {
            skipReason = message;
            skip = true;
        }
    }

    protected void skipIfXdtNotPresent()
    {
        File f = new File( System.getenv( "PROGRAMFILES" ), "MSBuild" );
        f = new File( f, "Microsoft/VisualStudio" );
        File[] versions = f.listFiles();
        if ( versions != null ) {
            for ( File v : versions )
            {
                if ( new File( v, "Web/Microsoft.Web.Publishing.Tasks.dll" ).exists() )
                {
                    return;
                }
            }
        }

        skipReason = "Visual Studio 2010 (or above) with web platform is not installed";
        skip = true;
    }

    protected void skipIfMissingWebDeployV2() {
        skipIfMissingProgramFilesDirectory("IIS/Microsoft Web Deploy V2", "Web Deploy 2.0 not installed");
    }

    protected void skipIfMissingAzureSDK(String sdkVersion) {
        if ("1.6".equals(sdkVersion)) {
            skipIfMissingProgramFilesDirectory( "Windows Azure SDK", "Azure SDK is not installed" );
        }
        else if ("1.7".equals(sdkVersion)) {
            skipIfMissingProgramFilesDirectory( "Microsoft SDKs\\Windows Azure\\.NET SDK\\2012-06", "Azure SDK is not installed" );
        }
        else {
            throw new IllegalArgumentException("Unknown SDK version: " + sdkVersion);
        }
    }

    protected void skipIfMissingMVC2() {
        skipIfMissingGAC( "System.Web.MVC", "MVC.NET is not installed" );
    }
}
