package org.apache.maven.plugin.surefire.booterclient;

/*
 * 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 org.apache.maven.surefire.shared.compress.archivers.zip.Zip64Mode;
import org.apache.maven.surefire.shared.compress.archivers.zip.ZipArchiveEntry;
import org.apache.maven.surefire.shared.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.OutputStreamFlushableCommandline;
import org.apache.maven.plugin.surefire.booterclient.output.InPluginProcessDumpSingleton;
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.surefire.booter.Classpath;
import org.apache.maven.surefire.booter.StartupConfiguration;
import org.apache.maven.surefire.booter.SurefireBooterForkException;
import org.apache.maven.surefire.extensions.ForkNodeFactory;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.jar.Manifest;
import java.util.zip.Deflater;

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.Files.isDirectory;
import static org.apache.maven.plugin.surefire.SurefireHelper.escapeToPlatformPath;
import static org.apache.maven.plugin.surefire.booterclient.JarManifestForkConfiguration.ClasspathElementUri.absolute;
import static org.apache.maven.plugin.surefire.booterclient.JarManifestForkConfiguration.ClasspathElementUri.relative;
import static org.apache.maven.surefire.util.internal.StringUtils.NL;

/**
 * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
 * @since 2.21.0.Jigsaw
 */
public final class JarManifestForkConfiguration
    extends AbstractClasspathForkConfiguration
{
    @SuppressWarnings( "checkstyle:parameternumber" )
    public JarManifestForkConfiguration( @Nonnull Classpath bootClasspath, @Nonnull File tempDirectory,
                                         @Nullable String debugLine, @Nonnull File workingDirectory,
                                         @Nonnull Properties modelProperties, @Nullable String argLine,
                                         @Nonnull Map<String, String> environmentVariables,
                                         @Nonnull String[] excludedEnvironmentVariables,
                                         boolean debug,
                                         int forkCount, boolean reuseForks, @Nonnull Platform pluginPlatform,
                                         @Nonnull ConsoleLogger log,
                                         @Nonnull ForkNodeFactory forkNodeFactory )
    {
        super( bootClasspath, tempDirectory, debugLine, workingDirectory, modelProperties, argLine,
            environmentVariables, excludedEnvironmentVariables, debug, forkCount, reuseForks, pluginPlatform, log,
            forkNodeFactory );
    }

    @Override
    protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
                                     @Nonnull String booterThatHasMainMethod,
                                     @Nonnull StartupConfiguration config,
                                     @Nonnull File dumpLogDirectory )
            throws SurefireBooterForkException
    {
        try
        {
            File jar = createJar( toCompleteClasspath( config ), booterThatHasMainMethod, dumpLogDirectory );
            cli.createArg().setValue( "-jar" );
            cli.createArg().setValue( escapeToPlatformPath( jar.getAbsolutePath() ) );
        }
        catch ( IOException e )
        {
            throw new SurefireBooterForkException( "Error creating archive file", e );
        }
    }

    /**
     * Create a jar with just a manifest containing a Main-Class entry for BooterConfiguration and a Class-Path entry
     * for all classpath elements.
     *
     * @param classPath      List&lt;String&gt; of all classpath elements.
     * @param startClassName The class name to start (main-class)
     * @return file of the jar
     * @throws IOException When a file operation fails.
     */
    @Nonnull
    private File createJar( @Nonnull List<String> classPath, @Nonnull String startClassName,
                            @Nonnull File dumpLogDirectory )
            throws IOException
    {
        File file = File.createTempFile( "surefirebooter", ".jar", getTempDirectory() );
        if ( !isDebug() )
        {
            file.deleteOnExit();
        }
        Path parent = file.getParentFile().toPath();
        OutputStream fos = new BufferedOutputStream( new FileOutputStream( file ), 64 * 1024 );

        try ( ZipArchiveOutputStream zos = new ZipArchiveOutputStream( fos ) )
        {
            zos.setUseZip64( Zip64Mode.Never );
            zos.setLevel( Deflater.NO_COMPRESSION );

            ZipArchiveEntry ze = new ZipArchiveEntry( "META-INF/MANIFEST.MF" );
            zos.putArchiveEntry( ze );

            Manifest man = new Manifest();

            boolean dumpError = true;

            // we can't use StringUtils.join here since we need to add a '/' to
            // the end of directory entries - otherwise the jvm will ignore them.
            StringBuilder cp = new StringBuilder();
            for ( Iterator<String> it = classPath.iterator(); it.hasNext(); )
            {
                Path classPathElement = Paths.get( it.next() );
                ClasspathElementUri classpathElementUri =
                        toClasspathElementUri( parent, classPathElement, dumpLogDirectory, dumpError );
                // too many errors in dump file with the same root cause may slow down the Boot Manifest-JAR startup
                dumpError &= !classpathElementUri.absolute;
                cp.append( classpathElementUri.uri );
                if ( isDirectory( classPathElement ) && !classpathElementUri.uri.endsWith( "/" ) )
                {
                    cp.append( '/' );
                }

                if ( it.hasNext() )
                {
                    cp.append( ' ' );
                }
            }

            man.getMainAttributes().putValue( "Manifest-Version", "1.0" );
            man.getMainAttributes().putValue( "Class-Path", cp.toString().trim() );
            man.getMainAttributes().putValue( "Main-Class", startClassName );

            man.write( zos );

            zos.closeArchiveEntry();

            return file;
        }
    }

    static String relativize( @Nonnull Path parent, @Nonnull Path child )
            throws IllegalArgumentException
    {
        return parent.relativize( child )
                .toString();
    }

    static String toAbsoluteUri( @Nonnull Path absolutePath )
    {
        return absolutePath.toUri()
                .toASCIIString();
    }

    static ClasspathElementUri toClasspathElementUri( @Nonnull Path parent,
                                         @Nonnull Path classPathElement,
                                         @Nonnull File dumpLogDirectory,
                                         boolean dumpError )
    {
        try
        {
            String relativePath = relativize( parent, classPathElement );
            return relative( escapeUri( relativePath, UTF_8 ) );
        }
        catch ( IllegalArgumentException e )
        {
            if ( dumpError )
            {
                String error = "Boot Manifest-JAR contains absolute paths in classpath '"
                        + classPathElement
                        + "'"
                        + NL
                        + "Hint: <argLine>-Djdk.net.URLClassPath.disableClassPathURLCheck=true</argLine>";
                InPluginProcessDumpSingleton.getSingleton()
                        .dumpStreamText( error, dumpLogDirectory );
            }

            return absolute( toAbsoluteUri( classPathElement ) );
        }
    }

    static final class ClasspathElementUri
    {
        final String uri;
        final boolean absolute;

        private ClasspathElementUri( String uri, boolean absolute )
        {
            this.uri = uri;
            this.absolute = absolute;
        }

        static ClasspathElementUri absolute( String uri )
        {
            return new ClasspathElementUri( uri, true );
        }

        static ClasspathElementUri relative( String uri )
        {
            return new ClasspathElementUri( uri, false );
        }
    }

    static String escapeUri( String input, Charset encoding )
    {
        try
        {
            String uriFormEncoded = URLEncoder.encode( input, encoding.name() );

            String uriPathEncoded = uriFormEncoded.replaceAll( "\\+", "%20" );
            uriPathEncoded = uriPathEncoded.replaceAll( "%2F|%5C", "/" );

            return uriPathEncoded;
        }
        catch ( UnsupportedEncodingException e )
        {
            throw new IllegalStateException( "avoided by using Charset" );
        }
    }
}
