/*
 * 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.sling.maven.slingstart;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Build;
import org.apache.maven.project.MavenProject;
import org.apache.sling.provisioning.model.Model;
import org.apache.sling.provisioning.model.io.ModelReader;
import org.codehaus.plexus.archiver.UnArchiver;
import org.codehaus.plexus.archiver.manager.ArchiverManager;
import org.junit.Test;
import org.mockito.Mockito;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;

public class PreparePackageMojoTest {
    @Test
    public void testBSNRenaming() throws Exception {
        // Provide the system with some artifacts that are known to be in the local .m2 repo
        // These are explicitly included in the test section of the pom.xml
        PreparePackageMojo ppm = getMojoUnderTest(
                "org.apache.sling/org.apache.sling.commons.classloader/1.3.2",
                "org.apache.sling/org.apache.sling.commons.classloader/1.3.2/app",
                "org.apache.sling/org.apache.sling.commons.johnzon/1.0.0");
        try {
            String modelTxt = "[feature name=:launchpad]\n" +
                    "[artifacts]\n" +
                    "  org.apache.sling/org.apache.sling.commons.classloader/1.3.2\n" +
                    "" +
                    "[feature name=rename_test]\n" +
                    "  org.apache.sling/org.apache.sling.commons.johnzon/1.0.0 [bundle:rename-bsn=r-foo.bar.renamed.sling.commons.johnzon]\n";

            Model model = ModelReader.read(new StringReader(modelTxt), null);
            ppm.execute(model);

            File orgJar = getMavenArtifactFile(getMavenRepoRoot(), "org.apache.sling", "org.apache.sling.commons.johnzon", "1.0.0");
            File generatedJar = new File(ppm.getTmpDir() + "/r-foo.bar.renamed.sling.commons.johnzon-1.0.0.jar");

            compareJarContents(orgJar, generatedJar);

            try (JarFile jfOrg = new JarFile(orgJar);
                JarFile jfNew = new JarFile(generatedJar)) {
                Manifest mfOrg = jfOrg.getManifest();
                Manifest mfNew = jfNew.getManifest();

                Attributes orgAttrs = mfOrg.getMainAttributes();
                Attributes newAttrs = mfNew.getMainAttributes();
                for (Object key : orgAttrs.keySet()) {
                    String orgVal = orgAttrs.getValue(key.toString());
                    String newVal = newAttrs.getValue(key.toString());

                    if ("Bundle-SymbolicName".equals(key.toString())) {
                        assertEquals("Should have recorded the original Bundle-SymbolicName",
                                orgVal, newAttrs.getValue("X-Original-Bundle-SymbolicName"));

                        assertEquals("r-foo.bar.renamed.sling.commons.johnzon", newVal);
                    } else {
                        assertEquals("Different keys: " + key, orgVal, newVal);
                    }
                }
            }
        } finally {
            FileUtils.deleteDirectory(new File(ppm.project.getBuild().getDirectory()));
        }
    }

    private static void compareJarContents(File orgJar, File actualJar) throws IOException {
        try (JarInputStream jis1 = new JarInputStream(new FileInputStream(orgJar));
            JarInputStream jis2 = new JarInputStream(new FileInputStream(actualJar))) {
            JarEntry je1 = null;
            while ((je1 = jis1.getNextJarEntry()) != null) {
                if (je1.isDirectory())
                    continue;

                JarEntry je2 = null;
                while((je2 = jis2.getNextJarEntry()) != null) {
                    if (!je2.isDirectory())
                        break;
                }

                assertEquals(je1.getName(), je2.getName());
                assertEquals(je1.getSize(), je2.getSize());

                try {
                    byte[] buf1 = IOUtils.toByteArray(jis1);
                    byte[] buf2 = IOUtils.toByteArray(jis2);

                    assertArrayEquals("Contents not equal: " + je1.getName(), buf1, buf2);
                } finally {
                    jis1.closeEntry();
                    jis2.closeEntry();
                }
            }
        }
    }

    @Test
    public void testSubsystemBaseGeneration() throws Exception {
        // Provide the system with some artifacts that are known to be in the local .m2 repo
        // These are explicitly included in the test section of the pom.xml
        PreparePackageMojo ppm = getMojoUnderTest(
                "org.apache.sling/org.apache.sling.commons.classloader/1.3.2",
                "org.apache.sling/org.apache.sling.commons.classloader/1.3.2/app",
                "org.apache.sling/org.apache.sling.commons.contentdetection/1.0.2",
                "org.apache.sling/org.apache.sling.commons.johnzon/1.0.0",
                "org.apache.sling/org.apache.sling.commons.mime/2.1.8",
                "org.apache.sling/org.apache.sling.commons.threads/3.2.0");

        try {
            // The launchpad feature is a prerequisite for the model
            String modelTxt =
                    "[feature name=:launchpad]\n" +
                    "[artifacts]\n" +
                    "  org.apache.sling/org.apache.sling.commons.classloader/1.3.2\n" +
                    "" +
                    "[feature name=test1 type=osgi.subsystem.composite]\n" +
                    "" +
                    "[:subsystem-manifest startLevel=123]\n" +
                    "  Subsystem-Description: Extra subsystem headers can go here including very long ones that would span multiple lines in a manifest\n" +
                    "  Subsystem-Copyright: (c) 2015 yeah!\n" +
                    "" +
                    "[artifacts startLevel=10]\n" +
                    "  org.apache.sling/org.apache.sling.commons.johnzon/1.0.0\n" +
                    "  org.apache.sling/org.apache.sling.commons.mime/2.1.8\n" +
                    "" +
                    "[artifacts startLevel=20 runModes=foo,bar,:blah]\n" +
                    "  org.apache.sling/org.apache.sling.commons.threads/3.2.0\n" +
                    "" +
                    "[artifacts startLevel=100 runModes=bar]\n" +
                    "  org.apache.sling/org.apache.sling.commons.contentdetection/1.0.2\n";
            Model model = ModelReader.read(new StringReader(modelTxt), null);
            ppm.execute(model);

            File generatedFile = new File(ppm.getTmpDir() + "/test1.subsystem-base");
            try (JarFile jf = new JarFile(generatedFile)) {
                // Test META-INF/MANIFEST.MF
                Manifest mf = jf.getManifest();
                Attributes attrs = mf.getMainAttributes();
                String expected = "Potential_Bundles/10/org.apache.sling.commons.johnzon-1.0.0.jar|"
                        + "Potential_Bundles/10/org.apache.sling.commons.mime-2.1.8.jar";
                assertEquals(expected, attrs.getValue("_all_"));
                assertEquals("Potential_Bundles/20/org.apache.sling.commons.threads-3.2.0.jar", attrs.getValue("foo"));
                assertEquals("Potential_Bundles/20/org.apache.sling.commons.threads-3.2.0.jar|"
                        + "Potential_Bundles/100/org.apache.sling.commons.contentdetection-1.0.2.jar", attrs.getValue("bar"));

                // Test SUBSYSTEM-MANIFEST-BASE.MF
                ZipEntry smbZE = jf.getEntry("SUBSYSTEM-MANIFEST-BASE.MF");
                try (InputStream smbIS = jf.getInputStream(smbZE)) {
                    Manifest smbMF = new Manifest(smbIS);
                    Attributes smbAttrs = smbMF.getMainAttributes();
                    assertEquals("test1", smbAttrs.getValue("Subsystem-SymbolicName"));
                    assertEquals("osgi.subsystem.composite", smbAttrs.getValue("Subsystem-Type"));
                    assertEquals("(c) 2015 yeah!", smbAttrs.getValue("Subsystem-Copyright"));
                    assertEquals("Extra subsystem headers can go here including very long ones "
                            + "that would span multiple lines in a manifest",
                            smbAttrs.getValue("Subsystem-Description"));
                }

                // Test embedded bundles
                File mrr = getMavenRepoRoot();

                File sjj = getMavenArtifactFile(mrr, "org.apache.sling", "org.apache.sling.commons.johnzon", "1.0.0");
                ZipEntry sjZE = jf.getEntry("Potential_Bundles/10/org.apache.sling.commons.johnzon-1.0.0.jar");
                try (InputStream is = jf.getInputStream(sjZE)) {
                    assertArtifactsEqual(sjj, is);
                }

                File smj = getMavenArtifactFile(mrr, "org.apache.sling", "org.apache.sling.commons.mime", "2.1.8");
                ZipEntry smjZE = jf.getEntry("Potential_Bundles/10/org.apache.sling.commons.mime-2.1.8.jar");
                try (InputStream is = jf.getInputStream(smjZE)) {
                    assertArtifactsEqual(smj, is);
                }

                File stj = getMavenArtifactFile(mrr, "org.apache.sling", "org.apache.sling.commons.threads", "3.2.0");
                ZipEntry stjZE = jf.getEntry("Potential_Bundles/20/org.apache.sling.commons.threads-3.2.0.jar");
                try (InputStream is = jf.getInputStream(stjZE)) {
                    assertArtifactsEqual(stj, is);
                }

                File ctj = getMavenArtifactFile(mrr, "org.apache.sling", "org.apache.sling.commons.contentdetection", "1.0.2");
                ZipEntry ctjZE = jf.getEntry("Potential_Bundles/100/org.apache.sling.commons.contentdetection-1.0.2.jar");
                try (InputStream is = jf.getInputStream(ctjZE)) {
                    assertArtifactsEqual(ctj, is);
                }
            }
        } finally {
            FileUtils.deleteDirectory(new File(ppm.project.getBuild().getDirectory()));
        }
    }

    private void assertArtifactsEqual(File f, InputStream is) throws IOException {
        byte[] bytes1 = Files.readAllBytes(f.toPath());
        byte[] bytes2 = IOUtils.toByteArray(is);
        assertArrayEquals("Bytes not equal on file " + f.getName(), bytes1, bytes2);
    }

    private PreparePackageMojo getMojoUnderTest(String ... knownArtifacts) throws Exception {
        File mrr = getMavenRepoRoot();

        ArtifactHandler ah = Mockito.mock(ArtifactHandler.class);
        ArtifactHandlerManager ahm = Mockito.mock(ArtifactHandlerManager.class);
        Mockito.when(ahm.getArtifactHandler(Mockito.anyString())).thenReturn(ah);

        Set<org.apache.maven.artifact.Artifact> artifacts = new HashSet<>();
        for (String s : knownArtifacts) {
            String[] parts = s.split("[/]");
            switch (parts.length) {
            case 3:
                artifacts.add(getMavenArtifact(mrr, ah, parts[0], parts[1], parts[2]));
                break;
            case 4:
                artifacts.add(getMavenArtifact(mrr, ah, parts[0], parts[1], parts[2], parts[3]));
                break;
            default: throw new IllegalStateException(s);
            }
        }

        MavenProject mavenPrj = new MavenProject();
        Build build = new Build();
        Path tempDir = Files.createTempDirectory(getClass().getSimpleName());
        build.setOutputDirectory(tempDir.toString());
        build.setDirectory(tempDir.toString());
        mavenPrj.setBuild(build);
        mavenPrj.setDependencyArtifacts(artifacts);

        PreparePackageMojo ppm = new PreparePackageMojo();
        ppm.mavenSession = Mockito.mock(MavenSession.class);
        ppm.project = mavenPrj;
        ArchiverManager am = Mockito.mock(ArchiverManager.class);
        UnArchiver ua = Mockito.mock(UnArchiver.class);
        Mockito.when(am.getUnArchiver(Mockito.isA(File.class))).thenReturn(ua);
        setPrivateField(ppm, "archiverManager", am);
        setPrivateField(ppm, "artifactHandlerManager", ahm);
        setPrivateField(ppm, "resolver", Mockito.mock(ArtifactResolver.class));
        return ppm;
    }

    private org.apache.maven.artifact.Artifact getMavenArtifact(File repoRoot, ArtifactHandler ah, String gid, String aid, String ver) {
        return getMavenArtifact(repoRoot, ah, gid, aid, ver, null);
    }

    private org.apache.maven.artifact.Artifact getMavenArtifact(File repoRoot, ArtifactHandler ah, String gid, String aid, String ver, String classifier) {
        DefaultArtifact art = new DefaultArtifact(gid, aid, ver, "compile", "jar", classifier, ah);
        art.setFile(getMavenArtifactFile(repoRoot, gid, aid, ver));
        return art;
    }

    private File getMavenArtifactFile(File repoRoot, String gid, String aid, String ver) {
        return new File(repoRoot, gid.replace('.', '/') + '/' + aid + '/' + ver + '/' + aid + '-' + ver + ".jar");
    }

    private File getMavenRepoRoot() throws IOException {
        URL res = getClass().getClassLoader().getResource(
                Test.class.getName().replace('.', '/') + ".class");

        String u = res.toExternalForm();
        if (u.startsWith("jar:"))
            u = u.substring(4);

        int idx = u.indexOf("junit");
        if (idx < 0)
            throw new IllegalStateException("Cannot infer maven repo root: " + res);

        return new File(new URL(u.substring(0, idx)).getFile());
    }

    private void setPrivateField(Object obj, String name, Object val) throws Exception {
        Field f = obj.getClass().getDeclaredField(name);
        f.setAccessible(true);
        f.set(obj, val);
    }
}
