/*
 * 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 static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.util.Properties;

import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Build;
import org.apache.maven.project.MavenProject;
import org.apache.sling.maven.slingstart.ModelPreprocessor.Environment;
import org.apache.sling.maven.slingstart.ModelPreprocessor.ProjectInfo;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;

public class FeatureModelConverterTest {
    private File tempDir;

    @Before
    public void setup() throws Exception {
        tempDir = Files.createTempDirectory(getClass().getSimpleName()).toFile();
    }

    @After
    public void tearDown() throws Exception {
        // Delete the temp dir again
        delTree(tempDir);
        tempDir = null;
    }

    private void delTree(File f) throws IOException {
        if (f.isDirectory()) {
            for (File c : f.listFiles())
                delTree(c);
        }
        if (!f.delete()) {
            throw new FileNotFoundException("Cannot delete: " + f);
        }
    }

    @Test
    public void testConvert() throws Exception {
        File f = new File(System.getProperty("user.home") + File.separatorChar + ".m2");
        ArtifactRepository localRepo = Mockito.mock(ArtifactRepository.class);
        Mockito.when(localRepo.getUrl()).thenReturn(f.toURI().toURL().toString());

        MavenSession session = Mockito.mock(MavenSession.class);
        Mockito.when(session.getLocalRepository()).thenReturn(localRepo);

        URL url = getClass().getResource("/features2/src/main/features/boot_gav.json");
        File projBaseDir = new File(url.toURI())
                .getParentFile().getParentFile().getParentFile().getParentFile();

        Build build = Mockito.mock(Build.class);
        Mockito.when(build.getDirectory()).thenReturn(tempDir.getAbsolutePath());

        MavenProject proj = Mockito.mock(MavenProject.class);
        Mockito.when(proj.getBasedir()).thenReturn(projBaseDir);
        Mockito.when(proj.getBuild()).thenReturn(build);
        Mockito.when(proj.getVersion()).thenReturn("1.0");

        ProjectInfo pi = new ProjectInfo();
        pi.project = proj;

        Environment env = new Environment();
        env.modelProjects.put("xyz", pi);
        env.session = session;

        FeatureModelConverter.convert(env);

        File expectedFile = new File(tempDir,
                "provisioning" + File.separatorChar + "converted" + File.separatorChar + "boot_gav.json.txt");
        assertTrue(expectedFile.exists());
        assertTrue(expectedFile.length() > 0);
    }

    @Test
    public void testConvertWithIncludes() throws Exception {
        File f = new File(System.getProperty("user.home") + File.separatorChar + ".m2");
        ArtifactRepository localRepo = Mockito.mock(ArtifactRepository.class);
        Mockito.when(localRepo.getUrl()).thenReturn(f.toURI().toURL().toString());

        MavenSession session = Mockito.mock(MavenSession.class);
        Mockito.when(session.getLocalRepository()).thenReturn(localRepo);

        URL url = getClass().getResource("/features3");
        File projBaseDir = new File(url.toURI());

        Build build = Mockito.mock(Build.class);
        Mockito.when(build.getDirectory()).thenReturn(tempDir.getAbsolutePath());

        MavenProject proj = Mockito.mock(MavenProject.class);
        Mockito.when(proj.getBasedir()).thenReturn(projBaseDir);
        Mockito.when(proj.getBuild()).thenReturn(build);
        Mockito.when(proj.getGroupId()).thenReturn("generated");
        Mockito.when(proj.getVersion()).thenReturn("0.0.1-SNAPSHOT");

        ProjectInfo pi = new ProjectInfo();
        pi.project = proj;

        Environment env = new Environment();
        env.modelProjects.put("xyz", pi);
        env.session = session;

        FeatureModelConverter.convert(env);

        File simpleProvFile = new File(tempDir,
                "provisioning" + File.separatorChar + "converted" + File.separatorChar + "simple.json.txt");
        String simpleProv = new String(Files.readAllBytes(simpleProvFile.toPath()));
        assertTrue(simpleProv.contains("org.apache.aries/org.apache.aries.util/1.1.3"));
        assertFalse(simpleProv.contains("org.apache.sling/org.apache.sling.commons.log/5.1.0"));

        File inheritsProvFile = new File(tempDir,
                "provisioning" + File.separatorChar + "converted" + File.separatorChar + "simple_inherits.json.txt");
        String inheritsProv = new String(Files.readAllBytes(inheritsProvFile.toPath()));
        assertTrue(inheritsProv.contains("org.apache.aries/org.apache.aries.util/1.1.3"));
        assertTrue(inheritsProv.contains("org.apache.sling/org.apache.sling.commons.log/5.1.0"));
    }

    @Test
    public void testReplaceVars() {
        MavenProject mp = Mockito.mock(MavenProject.class);

        Properties props = new Properties();
        props.put("foo", "bar");

        Mockito.when(mp.getGroupId()).thenReturn("abc");
        Mockito.when(mp.getArtifactId()).thenReturn("a.b.c");
        Mockito.when(mp.getVersion()).thenReturn("1.2.3-SNAPSHOT");
        Mockito.when(mp.getProperties()).thenReturn(props);

        assertEquals("xxxabcyyy", FeatureModelConverter.replaceVars(mp,
                "xxx${project.groupId}yyy"));
        assertEquals("xxxabcyyya.b.c1.2.3-SNAPSHOT", FeatureModelConverter.replaceVars(mp,
                "xxx${project.groupId}yyy${project.artifactId}${project.version}"));
        assertEquals("xxxabcyyya.b.c1.2.3.SNAPSHOT", FeatureModelConverter.replaceVars(mp,
                "xxx${project.groupId}yyy${project.artifactId}${project.osgiVersion}"));
        assertEquals("xxxbaryyy", FeatureModelConverter.replaceVars(mp, "xxx${foo}yyy"));
    }

    @Test
    public void testReplaceVarsFromSystemProperties() {
        Properties storedProps = new Properties();
        storedProps.putAll(System.getProperties());

        try {
            System.setProperty("blah", "hello");

            MavenProject mp = Mockito.mock(MavenProject.class);
            Mockito.when(mp.getVersion()).thenReturn("1");
            assertEquals("hello hello ${blaaah}", FeatureModelConverter.replaceVars(mp,
                    "${blah} ${blah} ${blaaah}"));
        } finally {
            // Restore the system properties
            System.setProperties(storedProps);
        }
    }
}
