/*******************************************************************************
 * Copyright (c) 2015, 2019 SAP SE and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    SAP SE - initial API and implementation
 *******************************************************************************/
package org.eclipse.tycho.pomless;

import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertThat;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.maven.model.InputLocation;
import org.apache.maven.model.InputSource;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
import org.apache.maven.model.building.ModelProcessor;
import org.apache.maven.model.io.ModelParseException;
import org.apache.maven.model.io.ModelReader;
import org.codehaus.plexus.PlexusTestCase;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.junit.Test;
import org.sonatype.maven.polyglot.mapping.Mapping;

public class TychoModelReaderTest extends PlexusTestCase {

    @Test
    public void testReadBundle() throws Exception {
        File buildProperties = new File(getPolyglotTestDir(), "bundle1/" + TychoBundleMapping.MANIFEST_MF_MARKER);
        Model model = getTychoModelReader(TychoBundleMapping.PACKAGING).read(buildProperties,
                createReaderOptions(buildProperties));
        assertEquals("4.0.0", model.getModelVersion());
        assertEquals("pomless.bundle", model.getArtifactId());
        assertEquals("Pomless Bundle", model.getName());
        assertEquals("0.1.0-SNAPSHOT", model.getVersion());
        assertEquals("eclipse-plugin", model.getPackaging());
        assertParent(model.getParent());
        assertLocation("bundle1/META-INF/MANIFEST.MF", model.getLocation(""));
    }

    @Test
    public void testReadBundle2() throws Exception {
        File buildProperties = new File(getPolyglotTestDir(), "bundle2/" + TychoBundleMapping.MANIFEST_MF_MARKER);
        Model model = getTychoModelReader(TychoBundleMapping.PACKAGING).read(buildProperties,
                createReaderOptions(buildProperties));
        assertEquals("4.0.0", model.getModelVersion());
        assertEquals("pomless.bundle", model.getArtifactId());
        assertEquals("Pomless Bundle", model.getName());
        assertEquals("0.1.0-SNAPSHOT", model.getVersion());
        assertEquals("eclipse-plugin", model.getPackaging());
        assertParent(model.getParent());
        assertLocation("bundle2/META-INF/MANIFEST.MF", model.getLocation(""));
    }

    @Test
    public void testReadBundle3() throws Exception {
        File buildProperties = new File(getPolyglotTestDir(), "bundle3/" + TychoBundleMapping.MANIFEST_MF_MARKER);
        Model model = getTychoModelReader(TychoBundleMapping.PACKAGING).read(buildProperties,
                createReaderOptions(buildProperties));
        assertEquals("4.0.0", model.getModelVersion());
        assertEquals("pomless.bundle", model.getArtifactId());
        assertEquals("Pomless Bundle", model.getName());
        assertEquals("0.1.0-SNAPSHOT", model.getVersion());
        assertEquals("eclipse-plugin", model.getPackaging());
        assertParent(model.getParent());
        assertLocation("bundle3/META-INF/MANIFEST.MF", model.getLocation(""));
    }

    @Test
    public void testReadTestBundle() throws Exception {
        File buildProperties = new File(getPolyglotTestDir(), "bundle1.tests/" + TychoBundleMapping.MANIFEST_MF_MARKER);
        Model model = getTychoModelReader(TychoBundleMapping.PACKAGING).read(buildProperties,
                createReaderOptions(buildProperties));
        assertEquals("pomless.bundle.tests", model.getArtifactId());
        assertEquals("1.0.1", model.getVersion());
        assertEquals("eclipse-test-plugin", model.getPackaging());
        assertParent(model.getParent());
        assertLocation("bundle1.tests/META-INF/MANIFEST.MF", model.getLocation(""));
    }

    @Test
    public void testReadFeature() throws Exception {
        File feature = new File(getPolyglotTestDir(), "feature/feature.xml");
        Model model = getTychoModelReader(TychoFeatureMapping.PACKAGING).read(feature, createReaderOptions(feature));
        assertEquals("pomless.feature", model.getArtifactId());
        assertEquals("Pomless Feature", model.getName());
        assertEquals("1.0.0-SNAPSHOT", model.getVersion());
        assertEquals("eclipse-feature", model.getPackaging());
        assertParent(model.getParent());
        assertLocation("feature/feature.xml", model.getLocation(""));
    }

    @Test
    public void testReadFeature2() throws Exception {
        File feature = new File(getPolyglotTestDir(), "feature2/feature.xml");
        Model model = getTychoModelReader(TychoFeatureMapping.PACKAGING).read(feature, createReaderOptions(feature));
        assertEquals("pomless.feature", model.getArtifactId());
        assertEquals("Pomless Feature 2", model.getName());
        assertEquals("Eclipse.org", model.getOrganization().getName());
        assertEquals("1.0.0-SNAPSHOT", model.getVersion());
        assertEquals("eclipse-feature", model.getPackaging());
        assertParent(model.getParent());
        assertLocation("feature2/feature.xml", model.getLocation(""));
    }

    @Test
    public void testMissingManifestOrFeature() throws Exception {
        File buildDir = new File(getTestResourcesDir(), "modelreader/missingManifestOrFeature/");
        assertNull(getMapping(TychoBundleMapping.PACKAGING).locatePom(buildDir));
        assertNull(getMapping(TychoFeatureMapping.PACKAGING).locatePom(buildDir));
        assertNull(getMapping(TychoRepositoryMapping.PACKAGING).locatePom(buildDir));
        assertNull(getMapping(TychoTargetMapping.PACKAGING).locatePom(buildDir));
    }

    @Test
    public void testIllFormedFeature() throws Exception {
        File featureXml = new File(getTestResourcesDir(), "modelreader/features/illFormed/feature.xml");
        try {
            getTychoModelReader(TychoFeatureMapping.PACKAGING).read(featureXml, createReaderOptions(featureXml));
            fail();
        } catch (ModelParseException e) {
            // expected
        }
    }

    @Test
    public void testFeatureWithoutId() throws Exception {
        File featureXml = new File(getTestResourcesDir(), "modelreader/features/missingId/feature.xml");
        try {
            getTychoModelReader(TychoFeatureMapping.PACKAGING).read(featureXml, createReaderOptions(featureXml));
            fail();
        } catch (ModelParseException e) {
            assertThat(e.getMessage(), containsString("missing or empty 'id' attribute in element 'feature'"));
        }
    }

    @Test
    public void testFeatureWithoutVersion() throws Exception {
        File featureXml = new File(getTestResourcesDir(), "modelreader/features/missingVersion/feature.xml");
        try {
            getTychoModelReader(TychoFeatureMapping.PACKAGING).read(featureXml, createReaderOptions(featureXml));
            fail();
        } catch (ModelParseException e) {
            assertThat(e.getMessage(), containsString("missing or empty 'version' attribute in element 'feature'"));
        }
    }

    @Test
    public void testBundleWithoutSymbolicName() throws Exception {
        File buildProperties = new File(getTestResourcesDir(),
                "modelreader/plugins/missingBsn/" + TychoBundleMapping.MANIFEST_MF_MARKER);
        try {
            getTychoModelReader(TychoBundleMapping.PACKAGING).read(buildProperties,
                    createReaderOptions(buildProperties));
            fail();
        } catch (ModelParseException e) {
            assertThat(e.getMessage(), containsString("Bundle-SymbolicName missing in"));
        }
    }

    @Test
    public void testBundleWithoutVersion() throws Exception {
        File buildProperties = new File(getTestResourcesDir(),
                "modelreader/plugins/missingVersion/" + TychoBundleMapping.MANIFEST_MF_MARKER);
        try {
            getTychoModelReader(TychoBundleMapping.PACKAGING).read(buildProperties,
                    createReaderOptions(buildProperties));
            fail();
        } catch (ModelParseException e) {
            assertThat(e.getMessage(), containsString("Bundle-Version missing in"));
        }
    }

    @Test
    public void testNoParent() throws Exception {
        File buildProperties = new File(getTestResourcesDir(),
                "modelreader/noParent/bundle/" + TychoBundleMapping.MANIFEST_MF_MARKER);
        try {
            getTychoModelReader(TychoBundleMapping.PACKAGING).read(buildProperties,
                    createReaderOptions(buildProperties));
            fail();
        } catch (IOException e) {
            assertThat(e.getMessage(), containsString("No parent pom file found in"));
        }
    }

    @Test
    public void testFindParent() throws Exception {
        File location = new File(getTestResourcesDir(),
                "modelreader/grandparentInheritance/bundle/" + TychoBundleMapping.MANIFEST_MF_MARKER);
        Model model = getTychoModelReader(TychoBundleMapping.PACKAGING).read(location, createReaderOptions(location));
        assertNotNull(model);
        Parent parentReference = model.getParent();
        assertEquals("bundle-parent", parentReference.getArtifactId());
        assertEquals("grandparent.groupid", parentReference.getGroupId());
        assertEquals("1.2.3", parentReference.getVersion());
    }

    @Test
    public void testReadProduct() throws ModelParseException, IOException, ComponentLookupException {
        File product = new File(getPolyglotTestDir(), "product/myproduct.product");
        Model model = getTychoModelReader(TychoRepositoryMapping.PACKAGING).read(product, createReaderOptions(product));
        assertEquals("4.0.0", model.getModelVersion());
        assertEquals("pomless.product.validproduct", model.getArtifactId());
        assertEquals("0.0.2-SNAPSHOT", model.getVersion());
        assertEquals("eclipse-repository", model.getPackaging());
        assertParent(model.getParent());
    }

    public ModelReader getTychoModelReader(String packaging) throws ComponentLookupException {
        return getMapping(packaging).getReader();
    }

    private Mapping getMapping(String packaging) throws ComponentLookupException {
        return lookup(Mapping.class, packaging);
    }

    @Test
    public void testProductWithoutUid() throws IOException, ComponentLookupException {
        try {
            File product = new File(getTestResourcesDir(), "modelreader/products/missingUid/myproduct.product");
            getTychoModelReader(TychoRepositoryMapping.PACKAGING).read(product, createReaderOptions(product));
            fail();
        } catch (ModelParseException e) {
            assertThat(e.getMessage(), containsString("missing or empty 'uid' attribute in element 'product'"));
        }
    }

    @Test
    public void testProductWithoutVersion() throws IOException, ComponentLookupException {
        File product = new File(getTestResourcesDir(), "modelreader/products/missingVersion/myproduct.product");
        getTychoModelReader(TychoRepositoryMapping.PACKAGING).read(product, createReaderOptions(product));
    }

    @Test()
    public void testIllFormedProduct() throws Exception {
        File product = new File(getTestResourcesDir(), "modelreader/products/illFormed/myproduct.product");
        try {
            getTychoModelReader(TychoRepositoryMapping.PACKAGING).read(product, createReaderOptions(product));
            fail();
        } catch (ModelParseException e) {
            //expected
        }
    }

    @Test
    public void testReadUpdateSite() throws ModelParseException, IOException, ComponentLookupException {
        File updatesite = new File(getTestResourcesDir(), "modelreader/updatesites/site/category.xml");
        Model model = getTychoModelReader(TychoRepositoryMapping.PACKAGING).read(updatesite,
                createReaderOptions(updatesite));
        assertEquals("4.0.0", model.getModelVersion());
        assertEquals("site.eclipse-repository", model.getArtifactId());
        assertEquals("0.0.1-SNAPSHOT", model.getVersion());
        assertEquals("eclipse-repository", model.getPackaging());
        assertParent(model.getParent());
    }

    private void assertParent(Parent parent) {
        assertNotNull(parent);
        assertEquals("testParent.groupId", parent.getGroupId());
        assertEquals("testparent", parent.getArtifactId());
        assertEquals("0.0.1-SNAPSHOT", parent.getVersion());
    }

    private void assertLocation(String expectedLocation, InputLocation location) {
        assertNotNull(location);
        assertEquals(0, location.getLineNumber());
        assertEquals(0, location.getColumnNumber());
        InputSource source = location.getSource();
        assertNotNull(source);
        assertEquals(new File(getPolyglotTestDir(), expectedLocation).toString(), source.getLocation());
        assertNotNull(source.getModelId());
        assertTrue(source.getModelId().matches("^testParent.groupId:.*:.*"));
    }

    private Map<String, String> createReaderOptions(File buildProperties) {
        Map<String, String> options = new HashMap<>();
        options.put(ModelProcessor.SOURCE, buildProperties.getAbsolutePath());
        return options;
    }

    private File getPolyglotTestDir() {
        return new File(getTestResourcesDir(), "testpomless/");
    }

    private File getTestResourcesDir() {
        return new File(getBasedir(), "src/test/resources/");
    }

}
