/*
 *  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
 *
 *      https://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.ivy.ant;

import java.io.File;
import java.io.IOException;

import org.apache.ivy.TestHelper;
import org.apache.ivy.core.IvyPatternHelper;
import org.apache.ivy.util.CacheCleaner;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;

import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.*;

public class IvyRetrieveTest {
    private static final String IVY_RETRIEVE_PATTERN = "build/test/lib/[organisation]/[module]/ivy-[revision].xml";

    private static final String RETRIEVE_PATTERN = "build/test/lib/[conf]/[artifact]-[revision].[type]";

    private File cache;

    private IvyRetrieve retrieve;

    private Project project;

    @Before
    public void setUp() {
        createCache();
        CacheCleaner.deleteDir(new File("build/test/lib"));
        project = TestHelper.newProject();
        project.setProperty("ivy.settings.file", "test/repositories/ivysettings.xml");

        retrieve = new IvyRetrieve();
        retrieve.setProject(project);
        System.setProperty("ivy.cache.dir", cache.getAbsolutePath());
        retrieve.setPattern(RETRIEVE_PATTERN);
    }

    private void createCache() {
        cache = new File("build/cache");
        cache.mkdirs();
    }

    @After
    public void tearDown() {
        CacheCleaner.deleteDir(cache);
        CacheCleaner.deleteDir(new File("build/test/lib"));
    }

    @Test
    public void testSimple() {
        project.setProperty("ivy.dep.file", "test/java/org/apache/ivy/ant/ivy-simple.xml");
        retrieve.execute();
        assertTrue(new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org1", "mod1.2", "2.0",
            "mod1.2", "jar", "jar")).exists());
    }

    @Test
    public void testRetrieveFileSetToNonEmptyDirectory() throws IOException {
        new File("build/test/lib").mkdirs();
        new File("build/test/lib/foo.txt").createNewFile(); // make sure the retrieve dir is not empty

        project.setProperty("ivy.dep.file", "test/java/org/apache/ivy/ant/ivy-simple.xml");

        retrieve.setSetId("testId");
        retrieve.execute();

        FileSet fileSet = project.getReference("testId");
        assertNotNull(fileSet);
        assertEquals(1, fileSet.size());
    }

    @Test
    public void testRetrieveEmptyFileSetToNonEmptyDirectory() throws IOException {
        new File("build/test/lib").mkdirs();
        new File("build/test/lib/foo.txt").createNewFile(); // make sure the retrieve dir is not empty

        project.setProperty("ivy.dep.file", "test/java/org/apache/ivy/ant/ivy-simple.xml");

        retrieve.setType("foo"); // make sure we don't retrieve anything
        retrieve.setSetId("setId");
        retrieve.setPathId("pathId");
        retrieve.execute();

        FileSet fileSet = project.getReference("setId");
        assertNotNull(fileSet);
        assertEquals(0, fileSet.size());

        Path path = project.getReference("pathId");
        assertNotNull(path);
        assertEquals(0, path.size());
    }

    @Test
    public void testRetrievePrivateWithWildcard() {
        project.setProperty("ivy.dep.file", "test/java/org/apache/ivy/ant/ivy-381.xml");
        retrieve.setConf("*");
        retrieve.execute();
        assertTrue(new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org1", "mod1.2", "1.1",
            "mod1.2", "jar", "jar", "public")).exists());
        assertTrue(new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org3", "mod3.2", "1.4",
            "mod3.2", "jar", "jar", "private")).exists());
    }

    /**
     * Test case for IVY-992.
     *
     * @see <a href="https://issues.apache.org/jira/browse/IVY-992">IVY-992</a>
     */
    @Test
    public void testValidateInIvySettings() {
        project.setProperty("ivy.dep.file", "test/java/org/apache/ivy/ant/ivy-latest-extra.xml");
        retrieve.getSettings().setValidate(false);
        retrieve.execute();

        assertTrue(new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org1", "mod1.2", "2.2",
            "mod1.2", "jar", "jar", "default")).exists());
    }

    @Test
    public void testInline() {
        // we first resolve another ivy file
        IvyResolve resolve = new IvyResolve();
        resolve.setProject(project);
        resolve.setFile(new File("test/java/org/apache/ivy/ant/ivy-latest.xml"));
        resolve.execute();

        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.2", "mod1.2", "jar", "jar").exists());

        // then we resolve a dependency directly
        retrieve.setOrganisation("org1");
        retrieve.setModule("mod1.2");
        retrieve.setRevision("2.0");
        retrieve.setInline(true);
        retrieve.execute();
        assertTrue(new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org1", "mod1.2", "2.0",
            "mod1.2", "jar", "jar")).exists());
    }

    @Test
    public void testWithConf() {
        project.setProperty("ivy.dep.file", "test/repositories/1/org6/mod6.2/ivys/ivy-0.4.xml");
        retrieve.execute();

        assertTrue(new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org6", "mod6.1", "0.4",
            "mod6.1", "jar", "jar", "default")).exists());
        assertTrue(new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org6", "mod6.1", "0.4",
            "mod6.1", "jar", "jar", "extension")).exists());
        assertTrue(new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org1", "mod1.2", "2.1",
            "mod1.2", "jar", "jar", "extension")).exists());
    }

    @Test
    public void testSync() throws Exception {
        project.setProperty("ivy.dep.file", "test/repositories/1/org6/mod6.2/ivys/ivy-0.4.xml");
        retrieve.setSync(true);

        File[] old = new File[] {
                new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org6", "mod6.1", "0.4",
                    "mod6.1", "jar", "jar", "unknown")), // unknown configuration
                new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org6", "mod6.1", "0.4",
                    "mod6.1", "unknown", "unknown", "default")), // unknown type
                new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org6", "mod6.1", "0.4",
                    "unknown", "jar", "jar", "default")), // unknown artifact
                new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org6", "mod6.1", "unknown",
                    "mod6.1", "jar", "jar", "default")), // unknown revision
        };
        for (File of : old) {
            touch(of);
        }
        retrieve.execute();

        assertTrue(new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org6", "mod6.1", "0.4",
            "mod6.1", "jar", "jar", "default")).exists());
        assertTrue(new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org6", "mod6.1", "0.4",
            "mod6.1", "jar", "jar", "extension")).exists());
        assertTrue(new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org1", "mod1.2", "2.1",
            "mod1.2", "jar", "jar", "extension")).exists());
        for (File of : old) {
            assertFalse(of + " should have been deleted by sync", of.exists());
        }
        assertFalse(new File("build/test/lib/unknown").exists()); // even conf directory should
        // have been deleted
    }

    @Test
    public void testSyncWithIgnoreList() throws Exception {
        project.setProperty("ivy.dep.file", "test/repositories/1/org6/mod6.2/ivys/ivy-0.4.xml");
        retrieve.setSync(true);

        new File("build/test/lib/.svn").mkdirs();
        new File("build/test/lib/.svn/test.txt").createNewFile();
        assertTrue(new File("build/test/lib/.svn/test.txt").exists());

        retrieve.execute();

        assertTrue(new File("build/test/lib/.svn/test.txt").exists());
    }

    @Test
    public void testWithAPreviousResolve() {
        // first we do a resolve in another project
        Project project = TestHelper.newProject();
        project.setProperty("ivy.settings.file", "test/repositories/ivysettings.xml");
        project.setProperty("ivy.dep.file", "test/java/org/apache/ivy/ant/ivy-simple.xml");
        IvyResolve resolve = new IvyResolve();
        resolve.setProject(project);
        resolve.execute();

        // then we do a retrieve with the correct module information
        retrieve.setOrganisation("apache");
        retrieve.setModule("resolve-simple");
        retrieve.setConf("default");
        retrieve.execute();

        assertTrue(new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org1", "mod1.2", "2.0",
            "mod1.2", "jar", "jar")).exists());
    }

    @Test
    public void testWithAPreviousResolveAndResolveId() {
        // first we do a resolve in another project
        Project project = TestHelper.newProject();
        project.setProperty("ivy.settings.file", "test/repositories/ivysettings.xml");
        project.setProperty("ivy.dep.file", "test/java/org/apache/ivy/ant/ivy-simple.xml");
        IvyResolve resolve = new IvyResolve();
        resolve.setProject(project);
        resolve.setResolveId("testWithAPreviousResolveAndResolveId");
        resolve.execute();

        // then we do a retrieve with the correct module information
        retrieve.setOrganisation("apache");
        retrieve.setModule("resolve-simple");
        retrieve.setConf("default");
        retrieve.setResolveId("testWithAPreviousResolveAndResolveId");
        retrieve.execute();

        assertTrue(new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org1", "mod1.2", "2.0",
            "mod1.2", "jar", "jar")).exists());
    }

    /**
     * Test case for IVY-304.
     *
     * @see <a href="https://issues.apache.org/jira/browse/IVY-304">IVY-304</a>
     */
    @Test
    public void testUseOrigin() {
        // first we do a resolve with useOrigin=true in another project
        Project project = TestHelper.newProject();
        project.init();
        project.setProperty("ivy.settings.file", "test/repositories/ivysettings.xml");
        project.setProperty("ivy.dep.file", "test/java/org/apache/ivy/ant/ivy-simple.xml");
        IvyResolve resolve = new IvyResolve();
        resolve.setProject(project);
        resolve.setUseOrigin(true);
        resolve.execute();

        // then we do a retrieve with the correct module information and useOrigin=false
        retrieve.setOrganisation("apache");
        retrieve.setModule("resolve-simple");
        retrieve.setConf("default");
        retrieve.setUseOrigin(false);
        retrieve.execute();

        assertTrue(new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org1", "mod1.2", "2.0",
            "mod1.2", "jar", "jar")).exists());
    }

    @Test
    public void testUseOriginWithIvyPattern() {
        // mod2.5 depends on virtual mod2.3 which depends on mod2.1 which depends on mod1.1 which
        // depends on mod1.2
        project.setProperty("ivy.dep.file", "test/repositories/1/org2/mod2.5/ivys/ivy-0.6.1.xml");

        String ivyPattern = IVY_RETRIEVE_PATTERN;

        retrieve.setIvypattern(ivyPattern);
        retrieve.setUseOrigin(true);
        retrieve.execute();

        assertTrue(new File(IvyPatternHelper.substitute(ivyPattern, "org2", "mod2.3", "0.4.1",
            "ivy", "ivy", "xml")).exists());
        assertTrue(new File(IvyPatternHelper.substitute(ivyPattern, "org2", "mod2.1", "0.3", "ivy",
            "ivy", "xml")).exists());
        assertTrue(new File(IvyPatternHelper.substitute(ivyPattern, "org1", "mod1.1", "1.0", "ivy",
            "ivy", "xml")).exists());
        assertFalse(new File(IvyPatternHelper.substitute(ivyPattern, "org1", "mod1.2", "2.0",
            "ivy", "ivy", "xml")).exists());
    }

    /**
     * Test case for IVY-631.
     *
     * @see <a href="https://issues.apache.org/jira/browse/IVY-631">IVY-631</a>
     */
    @Test
    public void testRetrieveWithOriginalNamePattern() {
        retrieve.setFile(new File("test/java/org/apache/ivy/ant/ivy-631.xml"));
        retrieve.setConf("default");
        retrieve.setPattern("build/test/lib/[conf]/[originalname].[ext]");
        retrieve.setSync(true);
        retrieve.execute();

        assertTrue(new File("build/test/lib/default/mod1.2-2.2.jar").exists());
    }

    /**
     * Retrieve without previous resolve must fail.
     */
    @Test(expected = BuildException.class)
    public void testFailureWithoutAPreviousResolve() {
        retrieve.setOrganisation("apache");
        retrieve.setModule("resolve-simple");
        retrieve.setConf("default");
        retrieve.execute();
    }

    /**
     * Test must fail with default haltonfailure setting.
     */
    @Test(expected = BuildException.class)
    public void testFailure() {
        project.setProperty("ivy.dep.file", "test/java/org/apache/ivy/ant/ivy-failure.xml");
        retrieve.execute();
    }

    @Test
    public void testHaltOnFailure() {
        project.setProperty("ivy.dep.file", "test/java/org/apache/ivy/ant/ivy-failure.xml");
        retrieve.setHaltonfailure(false);
        retrieve.execute();
    }

    @Test
    public void testCustomIvyPattern() {
        // mod2.5 depends on virtual mod2.3 which depends on mod2.1 which depends on mod1.1 which
        // depends on mod1.2
        project.setProperty("ivy.dep.file", "test/repositories/1/org2/mod2.5/ivys/ivy-0.6.1.xml");

        String ivyPattern = IVY_RETRIEVE_PATTERN;

        retrieve.setIvypattern(ivyPattern);
        retrieve.execute();

        assertTrue(new File(IvyPatternHelper.substitute(ivyPattern, "org2", "mod2.3", "0.4.1",
            "ivy", "ivy", "xml")).exists());
        assertTrue(new File(IvyPatternHelper.substitute(ivyPattern, "org2", "mod2.1", "0.3", "ivy",
            "ivy", "xml")).exists());
        assertTrue(new File(IvyPatternHelper.substitute(ivyPattern, "org1", "mod1.1", "1.0", "ivy",
            "ivy", "xml")).exists());
        assertFalse(new File(IvyPatternHelper.substitute(ivyPattern, "org1", "mod1.2", "2.0",
            "ivy", "ivy", "xml")).exists());
    }

    @Test
    public void testCustomIvyPatternWithConf() {
        project.setProperty("ivy.dep.file", "test/repositories/1/org6/mod6.2/ivys/ivy-0.4.xml");

        String ivyPattern = "build/test/lib/[conf]/[organisation]/[module]/ivy-[revision].xml";

        retrieve.setIvypattern(ivyPattern);
        retrieve.execute();

        assertTrue(new File(IvyPatternHelper.substitute(ivyPattern, "org6", "mod6.1", "0.4", "ivy",
            "ivy", "xml", "default")).exists());
        assertTrue(new File(IvyPatternHelper.substitute(ivyPattern, "org6", "mod6.1", "0.4", "ivy",
            "ivy", "xml", "extension")).exists());
        assertFalse(new File(IvyPatternHelper.substitute(ivyPattern, "org1", "mod1.2", "2.1",
            "ivy", "ivy", "xml", "extension")).exists());
    }

    @Test
    public void testSyncWithIvyPattern() throws Exception {
        project.setProperty("ivy.dep.file", "test/repositories/1/org6/mod6.2/ivys/ivy-0.4.xml");

        String ivyPattern = "build/test/lib/[conf]/[organisation]/[module]/ivy-[revision].xml";

        retrieve.setIvypattern(ivyPattern);

        retrieve.setSync(true);

        File[] old = new File[] {
                new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org6", "mod6.1", "0.4",
                    "mod6.1", "jar", "jar", "unknown")), // unknown configuration
                new File(IvyPatternHelper.substitute(RETRIEVE_PATTERN, "org6", "mod6.1", "0.4",
                    "mod6.1", "unknown", "unknown", "default")), // unknown type
                new File(IvyPatternHelper.substitute(ivyPattern, "org6", "mod6.1", "0.4", "ivy",
                    "ivy", "xml", "unk")), // unknown conf for ivy
                new File(IvyPatternHelper.substitute(ivyPattern, "unknown", "mod6.1", "0.4", "ivy",
                    "ivy", "xml", "default")), // unknown organisation for ivy
        };
        for (File of : old) {
            touch(of);
        }

        retrieve.execute();

        assertTrue(new File(IvyPatternHelper.substitute(ivyPattern, "org6", "mod6.1", "0.4", "ivy",
            "ivy", "xml", "default")).exists());
        assertTrue(new File(IvyPatternHelper.substitute(ivyPattern, "org6", "mod6.1", "0.4", "ivy",
            "ivy", "xml", "extension")).exists());
        assertFalse(new File(IvyPatternHelper.substitute(ivyPattern, "org1", "mod1.2", "2.1",
            "ivy", "ivy", "xml", "extension")).exists());
        for (File of : old) {
            assertFalse(of + " should have been deleted by sync", of.exists());
        }
        assertFalse(new File("build/test/lib/unknown").exists());
        assertFalse(new File("build/test/lib/unk").exists());
        assertFalse(new File("build/test/lib/default/unknown").exists());
    }

    /**
     * Test case for IVY-315.
     *
     * @see <a href="https://issues.apache.org/jira/browse/IVY-315">IVY-315</a>
     */
    @Test
    public void testDoubleRetrieveWithDifferentConfigurations() {
        project.setProperty("ivy.dep.file", "test/java/org/apache/ivy/ant/ivy-doubleretrieve.xml");

        retrieve.setConf("compile");
        retrieve.execute();

        retrieve = new IvyRetrieve();
        retrieve.setProject(project);
        retrieve.setPattern(RETRIEVE_PATTERN);
        retrieve.setConf("compile,unittest");
        retrieve.execute();
    }

    // creates an empty file, creating parent directories if necessary
    private void touch(File file) throws IOException {
        if (file.getParentFile() != null) {
            file.getParentFile().mkdirs();
        }
        file.createNewFile();
    }

    private File getArchiveFileInCache(String organisation, String module, String revision,
            String artifact, String type, String ext) {
        return TestHelper.getArchiveFileInCache(retrieve.getIvyInstance(), organisation, module,
            revision, artifact, type, ext);
    }

}
