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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.File;
import java.io.IOException;
import java.util.Deque;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedDeque;

import org.apache.maven.shared.utils.io.FileUtils;
import org.apache.maven.shared.verifier.Verifier;
import org.apache.maven.shared.verifier.util.ResourceExtractor;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.junit.jupiter.api.Test;

/**
 * This is a test set for <a href="https://issues.apache.org/jira/browse/MNG-3415">MNG-3415</a>.
 */
public class MavenITmng3415JunkRepositoryMetadataTest extends AbstractMavenIntegrationTestCase {
    private static final String RESOURCE_BASE = "/mng-3415";

    public MavenITmng3415JunkRepositoryMetadataTest() {
        // we're going to control the test execution according to the maven version present within each test method.
        // all methods should execute as long as we're using maven 2.0.9+, but the specific tests may vary a little
        // depending on which version we're using above 2.0.8.
        super("(2.0.8,)"); // only test in 2.0.9+
    }

    /**
     * This test simply verifies that when a metadata transfer fails (network error, etc.)
     * no metadata file is written to the local repository.
     * <p>
     * Steps executed to verify this test:
     * </p>
     * 0. Find the local repository directory:
     * a. build the maven-find-local-repo-plugin, then run it, to spit out the path of the
     * local repository in use by default. Read the output file to get this path.
     * (Yes, it's heavy, but it's reliable.)
     * 1. Setup the test:
     * a. Make sure the metadata for the test-repo is NOT in the local repository.
     * b. Make sure the dependency POM IS in the local repository, so we're not
     * distracted by failed builds that are unrelated.
     * c. Create the settings file for use in this test, which contains the invalid
     * remote repository entry.
     * 2. Build the test project the first time
     * a. Verify that a TransferFailedException is in the build output for the test-repo
     * b. Verify that the metadata for the dependency POM is NOT in the local
     * repository afterwards.
     * 3. Build the test project the second time
     * a. See (2.a) and (2.b) above; the same criteria applies here.
     *
     * @throws Exception in case of failure
     */
    @Test
    public void testitTransferFailed() throws Exception {
        String methodName = getMethodName();

        File testDir = ResourceExtractor.simpleExtractResources(getClass(), RESOURCE_BASE);

        Verifier verifier;

        verifier = newVerifier(testDir.getAbsolutePath());
        verifier.setAutoclean(false);
        verifier.deleteArtifacts("org.apache.maven.its.mng3415");

        setupDummyDependency(verifier, testDir, true);

        Map<String, String> filterProps = verifier.newDefaultFilterMap();
        filterProps.put("@protocol@", "invalid");
        filterProps.put("@port@", "0");
        File settings = verifier.filterFile("settings-template.xml", "settings-a.xml", "UTF-8", filterProps);

        verifier.addCliArgument("-X");
        verifier.addCliArgument("-s");
        verifier.addCliArgument(settings.getName());

        verifier.setLogFileName("log-" + methodName + "-firstBuild.txt");
        verifier.addCliArgument("validate");
        verifier.execute();

        verifier.verifyErrorFreeLog();

        assertMetadataMissing(verifier);

        setupDummyDependency(verifier, testDir, true);

        verifier.setLogFileName("log-" + methodName + "-secondBuild.txt");
        verifier.addCliArgument("validate");
        verifier.execute();

        verifier.verifyErrorFreeLog();

        assertMetadataMissing(verifier);
    }

    private String getMethodName() {
        return new Throwable().getStackTrace()[1].getMethodName();
    }

    /**
     * This test simply verifies that when metadata doesn't exist on the remote
     * repository, a basic metadata file is written to the local repository.
     * <p>
     * Steps executed to verify this test:
     * </p>
     * 0. Find the local repository directory:
     * a. build the maven-find-local-repo-plugin, then run it, to spit out the path of the
     * local repository in use by default. Read the output file to get this path.
     * (Yes, it's heavy, but it's reliable.)
     * 1. Setup the test:
     * a. Make sure the metadata for the test-repo is NOT in the local repository.
     * b. Make sure the dependency POM IS in the local repository, so we're not
     * distracted by failed builds that are unrelated.
     * c. Create the settings file for use in this test, which contains the VALID
     * remote repository entry.
     * 2. Build the test project the first time
     * a. Verify that the remote repository is checked for the metadata file
     * 3. Build the test project the second time
     * a. Verify that the remote repository is NOT checked for the metadata file again
     * b. Verify that the file used for updateInterval calculations was NOT changed from
     * the first build.
     *
     * @throws Exception in case of failure
     */
    @Test
    public void testShouldNotRepeatedlyUpdateOnResourceNotFoundException() throws Exception {
        String methodName = getMethodName();

        File testDir = ResourceExtractor.simpleExtractResources(getClass(), RESOURCE_BASE);

        Verifier verifier;

        verifier = newVerifier(testDir.getAbsolutePath());
        verifier.setAutoclean(false);
        verifier.deleteArtifacts("org.apache.maven.its.mng3415");

        final Deque<String> requestUris = new ConcurrentLinkedDeque<>();

        Handler repoHandler = new AbstractHandler() {
            @Override
            public void handle(
                    String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) {
                System.out.println("Handling " + request.getMethod() + " " + request.getRequestURL());

                requestUris.add(request.getRequestURI());

                response.setStatus(HttpServletResponse.SC_NOT_FOUND);

                ((Request) request).setHandled(true);
            }
        };

        Server server = new Server(0);
        server.setHandler(repoHandler);

        try {
            server.start();
            if (server.isFailed()) {
                fail("Couldn't bind the server socket to a free port!");
            }

            int port = ((NetworkConnector) server.getConnectors()[0]).getLocalPort();
            System.out.println("Bound server socket to the port " + port);

            Map<String, String> filterProps = verifier.newDefaultFilterMap();
            filterProps.put("@protocol@", "http");
            filterProps.put("@port@", Integer.toString(port));
            File settings = verifier.filterFile("settings-template.xml", "settings-b.xml", "UTF-8", filterProps);

            verifier.addCliArgument("-X");
            verifier.addCliArgument("-s");
            verifier.addCliArgument(settings.getName());

            setupDummyDependency(verifier, testDir, true);

            verifier.setLogFileName("log-" + methodName + "-firstBuild.txt");
            verifier.addCliArgument("validate");
            verifier.execute();

            verifier.verifyErrorFreeLog();

            assertTrue(
                    requestUris.toString(),
                    requestUris.contains("/org/apache/maven/its/mng3415/missing/1.0-SNAPSHOT/maven-metadata.xml"));

            requestUris.clear();

            File updateCheckFile = getUpdateCheckFile(verifier);
            long firstLastMod = updateCheckFile.lastModified();

            setupDummyDependency(verifier, testDir, false);

            verifier.setLogFileName("log-" + methodName + "-secondBuild.txt");
            verifier.addCliArgument("validate");
            verifier.execute();

            verifier.verifyErrorFreeLog();

            assertFalse(
                    requestUris.toString(),
                    requestUris.contains("/org/apache/maven/its/mng3415/missing/1.0-SNAPSHOT/maven-metadata.xml"));

            assertEquals(
                    "Last-modified time should be unchanged from first build through second build for the file we use for"
                            + " updateInterval checks.",
                    firstLastMod,
                    updateCheckFile.lastModified());
        } finally {
            server.stop();
            server.join();
        }
    }

    private void assertMetadataMissing(Verifier verifier) {
        File metadata = getMetadataFile(verifier);

        assertFalse(
                "Metadata file should NOT be present in local repository: " + metadata.getAbsolutePath(),
                metadata.exists());
    }

    private void setupDummyDependency(Verifier verifier, File testDir, boolean resetUpdateInterval) throws IOException {
        String gid = "org.apache.maven.its.mng3415";
        String aid = "missing";
        String version = "1.0-SNAPSHOT";

        if (resetUpdateInterval) {
            verifier.deleteArtifacts(gid);
        }

        File pom = new File(verifier.getArtifactPath(gid, aid, version, "pom"));

        File pomSrc = new File(testDir, "dependency-pom.xml");

        System.out.println("Copying dependency POM\nfrom: " + pomSrc + "\nto: " + pom);
        FileUtils.copyFile(pomSrc, pom);
    }

    private File getMetadataFile(Verifier verifier) {
        String gid = "org.apache.maven.its.mng3415";
        String aid = "missing";
        String version = "1.0-SNAPSHOT";
        String name = "maven-metadata-testing-repo.xml";

        return new File(verifier.getArtifactMetadataPath(gid, aid, version, name));
    }

    /**
     * If the current maven version is < 3.0, we'll use the metadata file itself (old maven-artifact code)...
     * otherwise, use the new resolver-status.properties file (new artifact code).
     */
    private File getUpdateCheckFile(Verifier verifier) {
        String gid = "org.apache.maven.its.mng3415";
        String aid = "missing";
        String version = "1.0-SNAPSHOT";
        String name;

        // < 3.0 (including snapshots)
        if (matchesVersionRange("(2.0.8,3.0-alpha-1)")) {
            name = "maven-metadata-testing-repo.xml";
        } else {
            name = "resolver-status.properties";
        }

        return new File(verifier.getArtifactMetadataPath(gid, aid, version, name));
    }
}
