/*
 * 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 org.apache.logging.log4j.plugins.util;

import org.apache.logging.log4j.junit.CleanFolders;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;

import javax.tools.*;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.nio.file.*;
import java.util.*;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;

/**
 * Tests the ResolverUtil class.
 */
public class ResolverUtilTest {

    static final String WORK_DIR = "target/testpluginsutil";

    @Rule
    public RuleChain chain = RuleChain.outerRule(new CleanFolders(WORK_DIR));
    
    @Test
    public void testExtractPathFromJarUrl() throws Exception {
        final URL url = new URL("jar:file:/C:/Users/me/.m2/repository/junit/junit/4.11/junit-4.11.jar!/org/junit/Test.class");
        final String expected = "/C:/Users/me/.m2/repository/junit/junit/4.11/junit-4.11.jar";
        assertEquals(expected, new ResolverUtil().extractPath(url));
    }

    @Test
    public void testExtractPathFromJarUrlNotDecodedIfFileExists() throws Exception {
        testExtractPathFromJarUrlNotDecodedIfFileExists("/log4j+config+with+plus+characters.xml");
    }

    private void testExtractPathFromJarUrlNotDecodedIfFileExists(final String existingFile)
            throws MalformedURLException, UnsupportedEncodingException, URISyntaxException {
        URL url = ResolverUtilTest.class.getResource(existingFile);
        assertNotNull("No url returned for " + existingFile, url);
        if (!url.getProtocol().equals("jar")) {
            // create fake jar: URL that resolves to existing file
            url = new URL("jar:" + url.toExternalForm() + "!/some/entry");
        }
        final String actual = new ResolverUtil().extractPath(url);
        assertTrue("should not be decoded: " + actual, actual.endsWith(existingFile));
    }

    @Test
    public void testFileFromUriWithSpacesAndPlusCharactersInName() throws Exception {
        final String existingFile = "/s p a c e s/log4j+config+with+plus+characters.xml";
        testExtractPathFromJarUrlNotDecodedIfFileExists(existingFile);
    }

    @Test
    public void testExtractPathFromJarUrlDecodedIfFileDoesNotExist() throws Exception {
        final URL url = new URL("jar:file:/path+with+plus/file+does+not+exist.jar!/some/file");
        final String expected = "/path with plus/file does not exist.jar";
        assertEquals(expected, new ResolverUtil().extractPath(url));
    }

    @Test
    public void testExtractPathFromFileUrl() throws Exception {
        final URL url = new URL("file:/C:/Users/me/workspace/log4j2/log4j-core/target/test-classes/log4j2-config.xml");
        final String expected = "/C:/Users/me/workspace/log4j2/log4j-core/target/test-classes/log4j2-config.xml";
        assertEquals(expected, new ResolverUtil().extractPath(url));
    }

    @Test
    public void testExtractPathFromFileUrlNotDecodedIfFileExists() throws Exception {
        final String existingFile = "/log4j+config+with+plus+characters.xml";
        final URL url = ResolverUtilTest.class.getResource(existingFile);
        assertTrue("should be file url but was " + url, "file".equals(url.getProtocol()));

        final String actual = new ResolverUtil().extractPath(url);
        assertTrue("should not be decoded: " + actual, actual.endsWith(existingFile));
    }

    @Test
    public void testExtractPathFromFileUrlDecodedIfFileDoesNotExist() throws Exception {
        final URL url = new URL("file:///path+with+plus/file+does+not+exist.xml");
        final String expected = "/path with plus/file does not exist.xml";
        assertEquals(expected, new ResolverUtil().extractPath(url));
    }

    @Test
    public void testExtractPathFromHttpUrl() throws Exception {
        final URL url = new URL("http://java.sun.com/index.html#chapter1");
        final String expected = "/index.html";
        assertEquals(expected, new ResolverUtil().extractPath(url));
    }

    @Test
    public void testExtractPathFromHttpUrlWithPlusCharacters() throws Exception {
        final URL url = new URL("http://www.server.com/path+with+plus/file+name+with+plus.jar!/org/junit/Test.class");
        final String expected = "/path with plus/file name with plus.jar";
        assertEquals(expected, new ResolverUtil().extractPath(url));
    }

    @Test
    public void testExtractPathFromHttpsComplexUrl() throws Exception {
        final URL url = new URL("https://issues.apache.org/jira/browse/LOG4J2-445?focusedCommentId=13862479&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-13862479");
        final String expected = "/jira/browse/LOG4J2-445";
        assertEquals(expected, new ResolverUtil().extractPath(url));
    }

    @Test
    public void testExtractPathFromFtpUrl() throws Exception {
        final URL url = new URL("ftp://user001:secretpassword@private.ftp-servers.example.com/mydirectory/myfile.txt");
        final String expected = "/mydirectory/myfile.txt";
        assertEquals(expected, new ResolverUtil().extractPath(url));
    }

    @Test
    public void testExtractPathFromFtpUrlWithPlusCharacters() throws Exception {
        final URL url = new URL("ftp://user001:secretpassword@private.ftp-servers.example.com/my+directory/my+file.txt");
        final String expected = "/my directory/my file.txt";
        assertEquals(expected, new ResolverUtil().extractPath(url));
    }

    @Test
    public void testFindInPackageFromDirectoryPath() throws Exception {
        try (final URLClassLoader cl = compileAndCreateClassLoader("1")) {
            final ResolverUtil resolverUtil = new ResolverUtil();
            resolverUtil.setClassLoader(cl);
            resolverUtil.findInPackage(new PluginRegistry.PluginTest(), "customplugin1");
            assertEquals("Class not found in packages", 1, resolverUtil.getClasses().size());
            assertEquals("Unexpected class resolved", cl.loadClass("customplugin1.FixedString1"),
                    resolverUtil.getClasses().iterator().next());
        }
    }

    @Test
    public void testFindInPackageFromJarPath() throws Exception {
        try (final URLClassLoader cl = compileJarAndCreateClassLoader("2")) {
            final ResolverUtil resolverUtil = new ResolverUtil();
            resolverUtil.setClassLoader(cl);
            resolverUtil.findInPackage(new PluginRegistry.PluginTest(), "customplugin2");
            assertEquals("Class not found in packages", 1, resolverUtil.getClasses().size());
            assertEquals("Unexpected class resolved", cl.loadClass("customplugin2.FixedString2"),
                    resolverUtil.getClasses().iterator().next());
        }
    }

    static URLClassLoader compileJarAndCreateClassLoader(final String suffix) throws IOException, Exception {
        final File workDir = compile(suffix);
        final File jarFile = new File(workDir, "customplugin" + suffix + ".jar");
        final URI jarURI = jarFile.toURI();
        createJar(jarURI, workDir, new File(workDir,
              "customplugin" + suffix + "/FixedString" + suffix + ".class"));
        return URLClassLoader.newInstance(new URL[] {jarURI.toURL()});
    }

    static URLClassLoader compileAndCreateClassLoader(final String suffix) throws IOException {
        final File workDir = compile(suffix);
        return URLClassLoader.newInstance(new URL[] {workDir.toURI().toURL()});
    }

    static File compile(final String suffix) throws IOException {
        final File orig = new File("target/test-classes/customplugin/FixedString.java.source");
        final File workDir = new File(WORK_DIR, "resolverutil" + suffix);
        final File f = new File(workDir, "customplugin" + suffix + "/FixedString" + suffix + ".java");
        final File parent = f.getParentFile();
        if (!parent.exists()) {
          assertTrue("Create customplugin" + suffix + " folder KO", f.getParentFile().mkdirs());
        }
  
        final String content = new String(Files.readAllBytes(orig.toPath()))
          .replaceAll("FixedString", "FixedString" + suffix)
          .replaceAll("customplugin", "customplugin" + suffix);
        Files.write(f.toPath(), content.getBytes());
  
        compile(f);
        return workDir;
    }

    static void createJar(final URI jarURI, final File workDir, final File f) throws Exception {
        final Map<String, String> env = new HashMap<>(); 
        env.put("create", "true");
        final URI uri = URI.create("jar:file://" + jarURI.getRawPath());
        try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {   
            final Path path = zipfs.getPath(workDir.toPath().relativize(f.toPath()).toString());
            if (path.getParent() != null) {
                Files.createDirectories(path.getParent());
            }
            Files.copy(f.toPath(),
                   path, 
                   StandardCopyOption.REPLACE_EXISTING ); 
        } 
    }

    static void compile(final File f) throws IOException {
        // set up compiler
        final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        final DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
        final List<String> errors = new ArrayList<>();
        try (final StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null)) {
            final Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(Arrays
                .asList(f));

            // compile generated source
            // (switch off annotation processing: no need to create Log4j2Plugins.dat)
            final List<String> options = Arrays.asList("-proc:none");
            compiler.getTask(null, fileManager, diagnostics, options, null, compilationUnits).call();

            // check we don't have any compilation errors
            for (final Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
                if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
                    errors.add(String.format("Compile error at line %d, column %d: %s%n", diagnostic.getLineNumber(),
                        diagnostic.getColumnNumber(), diagnostic.getMessage(Locale.getDefault())));
                }
            }
        }
        assertTrue(errors.toString(), errors.isEmpty());
    }

}
