/*
 * 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.plugins.pmd;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Locale;

import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import net.sourceforge.pmd.renderers.Renderer;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugins.pmd.exec.PmdExecutor;
import org.apache.maven.reporting.MavenReportException;
import org.codehaus.plexus.util.FileUtils;

/**
 * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
 * @version $Id$
 */
public class PmdReportTest extends AbstractPmdReportTestCase {

    /**
     * {@inheritDoc}
     */
    @Override
    protected void setUp() throws Exception {
        super.setUp();
        Locale.setDefault(Locale.ENGLISH);
        FileUtils.deleteDirectory(new File(getBasedir(), "target/test/unit"));
    }

    public void testDefaultConfiguration() throws Exception {
        FileUtils.copyDirectoryStructure(
                new File(getBasedir(), "src/test/resources/unit/default-configuration/jxr-files"),
                new File(getBasedir(), "target/test/unit/default-configuration/target/site"));

        File generatedReport = generateReport("pmd", "default-configuration/default-configuration-plugin-config.xml");
        assertTrue(FileUtils.fileExists(generatedReport.getAbsolutePath()));

        // check if the PMD files were generated
        File generatedFile = new File(getBasedir(), "target/test/unit/default-configuration/target/pmd.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        // check if the rulesets, that have been applied, have been copied
        generatedFile = new File(
                getBasedir(),
                "target/test/unit/default-configuration/target/pmd/rulesets/maven-pmd-plugin-default.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        // check if there's a link to the JXR files
        String str = readFile(generatedReport);

        assertTrue(str.contains("/xref/def/configuration/App.html#L31"));

        assertTrue(str.contains("/xref/def/configuration/AppSample.html#L45"));

        // check if there's a priority column
        assertTrue(str.contains("<th>Priority</th>"));

        // there should be a rule column
        assertTrue(str.contains("<th>Rule</th>"));
        // along with a link to the rule
        assertTrue(str.contains("pmd_rules_java_bestpractices.html#unusedprivatefield\">UnusedPrivateField</a>"));

        // there should be the section Violations By Priority
        assertTrue(str.contains("Violations By Priority</h3>"));
        assertTrue(str.contains("Priority 3</h4>"));
        assertTrue(str.contains("Priority 4</h4>"));
        // the file App.java is mentioned 3 times: in prio 3, in prio 4 and in the files section
        assertEquals(3, StringUtils.countMatches(str, "def/configuration/App.java"));

        // there must be no warnings (like deprecated rules) in the log output
        String output = CapturingPrintStream.getOutput();
        assertFalse(output.contains("deprecated Rule name"));
        assertFalse(output.contains("Discontinue using Rule name"));
        assertFalse(output.contains("is referenced multiple times"));

        // the version should be logged
        assertTrue(output.contains("PMD version: " + AbstractPmdReport.getPmdVersion()));
    }

    public void testDefaultConfigurationNotRenderRuleViolationPriority() throws Exception {
        FileUtils.copyDirectoryStructure(
                new File(getBasedir(), "src/test/resources/unit/default-configuration/jxr-files"),
                new File(getBasedir(), "target/test/unit/default-configuration/target/site"));

        File generatedReport =
                generateReport("pmd", "default-configuration/pmd-report-not-render-rule-priority-plugin-config.xml");
        assertTrue(FileUtils.fileExists(generatedReport.getAbsolutePath()));

        String str = readFile(generatedReport);

        // check that there's no priority column
        assertFalse(str.contains("<th>Priority</th>"));
    }

    public void testDefaultConfigurationNoRenderViolationsByPriority() throws Exception {
        FileUtils.copyDirectoryStructure(
                new File(getBasedir(), "src/test/resources/unit/default-configuration/jxr-files"),
                new File(getBasedir(), "target/test/unit/default-configuration/target/site"));

        File generatedReport =
                generateReport("pmd", "default-configuration/pmd-report-no-render-violations-by-priority.xml");
        assertTrue(FileUtils.fileExists(generatedReport.getAbsolutePath()));

        String str = readFile(generatedReport);

        // there should be no section Violations By Priority
        assertFalse(str.contains("Violations By Priority</h2>"));
        assertFalse(str.contains("Priority 3</h3>"));
        assertFalse(str.contains("Priority 4</h3>"));
        // the file App.java is mentioned once: in the files section
        assertEquals(1, StringUtils.countMatches(str, "def/configuration/App.java"));
    }

    public void testDefaultConfigurationWithAnalysisCache() throws Exception {
        FileUtils.copyDirectoryStructure(
                new File(getBasedir(), "src/test/resources/unit/default-configuration/jxr-files"),
                new File(getBasedir(), "target/test/unit/pmd-with-analysis-cache-plugin-config/target/site"));

        generateReport("pmd", "default-configuration/pmd-with-analysis-cache-plugin-config.xml");

        // check if the PMD analysis cache file has been generated
        File cacheFile =
                new File(getBasedir(), "target/test/unit/pmd-with-analysis-cache-plugin-config/target/pmd/pmd.cache");
        assertTrue(FileUtils.fileExists(cacheFile.getAbsolutePath()));
    }

    public void testJavascriptConfiguration() throws Exception {
        File generatedReport =
                generateReport("pmd", "default-configuration/javascript-configuration-plugin-config.xml");
        assertTrue(FileUtils.fileExists(generatedReport.getAbsolutePath()));

        // check if the PMD files were generated
        File generatedFile = new File(getBasedir(), "target/test/unit/default-configuration/target/pmd.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        // these are the rulesets, that have been applied...
        generatedFile =
                new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/bestpractices.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        generatedFile =
                new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/codestyle.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        generatedFile =
                new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/errorprone.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        String str = readFile(generatedReport);
        assertTrue(str.contains("Avoid using global variables"));
    }

    public void testFileURL() throws Exception {
        FileUtils.copyDirectoryStructure(
                new File(getBasedir(), "src/test/resources/unit/default-configuration/jxr-files"),
                new File(getBasedir(), "target/test/unit/default-configuration/target/site"));

        File testPom = new File(
                getBasedir(), "src/test/resources/unit/default-configuration/default-configuration-plugin-config.xml");
        PmdReport mojo = (PmdReport) createReportMojo("pmd", testPom);

        // Additional test case for MPMD-174 (https://issues.apache.org/jira/browse/MPMD-174).
        int port = determineFreePort();
        WireMockServer mockServer = new WireMockServer(port);
        mockServer.start();

        String sonarRuleset = IOUtils.toString(
                getClass()
                        .getClassLoader()
                        .getResourceAsStream("unit/default-configuration/rulesets/sonar-way-ruleset.xml"),
                StandardCharsets.UTF_8);

        String sonarMainPageHtml = IOUtils.toString(
                getClass()
                        .getClassLoader()
                        .getResourceAsStream("unit/default-configuration/rulesets/sonar-main-page.html"),
                StandardCharsets.UTF_8);

        final String sonarBaseUrl = "/profiles";
        final String sonarProfileUrl = sonarBaseUrl + "/export?format=pmd&language=java&name=Sonar%2520way";
        final String sonarExportRulesetUrl = "http://localhost:" + mockServer.port() + sonarProfileUrl;

        WireMock.configureFor("localhost", port);
        WireMock.stubFor(WireMock.get(WireMock.urlEqualTo(sonarBaseUrl))
                .willReturn(WireMock.aResponse()
                        .withStatus(200)
                        .withHeader("Content-Type", "text/html")
                        .withBody(sonarMainPageHtml)));

        WireMock.stubFor(WireMock.get(WireMock.urlEqualTo(sonarProfileUrl))
                .willReturn(WireMock.aResponse()
                        .withStatus(200)
                        .withHeader("Content-Type", "text/xml")
                        .withBody(sonarRuleset)));

        URL url = getClass().getClassLoader().getResource("rulesets/java/basic.xml");
        URL url2 = getClass().getClassLoader().getResource("rulesets/java/unusedcode.xml");
        URL url3 = getClass().getClassLoader().getResource("rulesets/java/imports.xml");
        mojo.setRulesets(new String[] {url.toString(), url2.toString(), url3.toString(), sonarExportRulesetUrl});

        File generatedReport = generateReport(mojo, testPom);
        assertTrue(FileUtils.fileExists(generatedReport.getAbsolutePath()));

        // check if the PMD files were generated
        File generatedFile = new File(getBasedir(), "target/test/unit/default-configuration/target/pmd.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        // the resolved and extracted rulesets
        generatedFile = new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/basic.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        generatedFile =
                new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/imports.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        generatedFile =
                new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/unusedcode.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        generatedFile = new File(
                getBasedir(),
                "target/test/unit/default-configuration/target/pmd/rulesets/export_format_pmd_language_java_name_Sonar_2520way.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        // check if there's a link to the JXR files
        String str = readFile(generatedReport);

        assertTrue(str.contains("/xref/def/configuration/App.html#L31"));

        assertTrue(str.contains("/xref/def/configuration/AppSample.html#L45"));

        mockServer.stop();
    }

    private int determineFreePort() {
        try (ServerSocket socket = new ServerSocket(0)) {
            return socket.getLocalPort();
        } catch (IOException e) {
            throw new RuntimeException("Couldn't find a free port.", e);
        }
    }

    /**
     * With custom rulesets
     *
     * @throws Exception
     */
    public void testCustomConfiguration() throws Exception {
        File generatedReport = generateReport("pmd", "custom-configuration/custom-configuration-plugin-config.xml");
        assertTrue(FileUtils.fileExists(generatedReport.getAbsolutePath()));

        // check the generated files
        File generatedFile = new File(getBasedir(), "target/test/unit/custom-configuration/target/pmd.csv");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        generatedFile = new File(getBasedir(), "target/test/unit/custom-configuration/target/pmd/rulesets/custom.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        // check if custom ruleset was applied
        String str = readFile(generatedReport);

        // codestyle.xml/ControlStatementBraces:
        assertTrue(lowerCaseContains(str, "This statement should have braces"));

        // Must be false as codestyle.xml/ControlStatementBraces with checkIfElseStmt=false is used
        assertFalse(lowerCaseContains(str, "Avoid using if...else statements without curly braces"));

        assertFalse(
                "unnecessary constructor should not be triggered because of low priority",
                lowerCaseContains(str, "Avoid unnecessary constructors - the compiler will generate these for you"));

        // veryLongVariableNameWithViolation is really too long
        assertTrue(lowerCaseContains(str, "veryLongVariableNameWithViolation"));
        // notSoLongVariableName should not be reported
        assertFalse(lowerCaseContains(str, "notSoLongVariableName"));
    }

    /**
     * Verify skip parameter
     *
     * @throws Exception
     */
    public void testSkipConfiguration() throws Exception {
        File generatedReport = generateReport("pmd", "custom-configuration/skip-plugin-config.xml");
        assertFalse(FileUtils.fileExists(generatedReport.getAbsolutePath()));

        // verify the generated files do not exist because PMD was skipped
        File generatedFile = new File(getBasedir(), "target/test/unit/skip-configuration/target/pmd.csv");
        assertFalse(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        generatedFile = new File(getBasedir(), "target/test/unit/custom-configuration/target/custom.xml");
        assertFalse(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        // the fact, the PMD execution has been skipped, should be logged
        String output = CapturingPrintStream.getOutput();
        assertTrue(output.contains("Skipping PMD execution"));
    }

    public void testSkipEmptyReportConfiguration() throws Exception {
        // verify the generated files do not exist because PMD was skipped
        File generatedReport = generateReport("pmd", "empty-report/skip-empty-report-plugin-config.xml");
        assertFalse(FileUtils.fileExists(generatedReport.getAbsolutePath()));
    }

    public void testEmptyReportConfiguration() throws Exception {
        File generatedReport = generateReport("pmd", "empty-report/empty-report-plugin-config.xml");
        assertTrue(FileUtils.fileExists(generatedReport.getAbsolutePath()));

        // verify the generated files do exist, even if there are no violations
        String str = readFile(generatedReport);
        assertFalse(lowerCaseContains(str, "Hello.java"));
        assertEquals(1, StringUtils.countMatches(str, "PMD found no problems in your source code."));
        // no sections files or violations by priority
        assertFalse(str.contains("Files</h2>"));
        assertFalse(str.contains("Violations By Priority</h2>"));
    }

    public void testInvalidFormat() throws Exception {
        try {
            File testPom =
                    new File(getBasedir(), "src/test/resources/unit/invalid-format/invalid-format-plugin-config.xml");
            AbstractPmdReport mojo = createReportMojo("pmd", testPom);
            setVariableValueToObject(
                    mojo, "compileSourceRoots", mojo.getProject().getCompileSourceRoots());
            generateReport(mojo, testPom);

            fail("Must throw MavenReportException.");
        } catch (Exception e) {
            assertTrue(true);
        }
    }

    public void testInvalidTargetJdk() throws Exception {
        try {
            generateReport("pmd", "empty-report/invalid-format/invalid-target-jdk-plugin-config.xml");

            fail("Must throw MavenReportException.");
        } catch (Exception e) {
            assertTrue(true);
        }
    }

    /**
     * verify the pmd.xml file is included in the site when requested.
     * @throws Exception
     */
    public void testIncludeXmlInSite() throws Exception {
        File generatedReport =
                generateReport("pmd", "default-configuration/pmd-report-include-xml-in-site-plugin-config.xml");
        assertTrue(FileUtils.fileExists(generatedReport.getAbsolutePath()));

        // verify the pmd file is included in site
        File generatedXmlFile = new File(getBasedir(), "target/test/unit/default-configuration/target/site/pmd.xml");
        assertTrue(FileUtils.fileExists(generatedXmlFile.getAbsolutePath()));

        String pmdXmlTarget = readFile(new File(getBasedir(), "target/test/unit/default-configuration/target/pmd.xml"));
        assertTrue(pmdXmlTarget.contains("</pmd>"));

        // check that pmd.xml file has the closing element
        String pmdXml = readFile(generatedXmlFile);
        assertTrue(pmdXml.contains("</pmd>"));
    }

    /**
     * Read the contents of the specified file object into a string
     *
     * @param file the file to be read
     * @return a String object that contains the contents of the file
     * @throws java.io.IOException
     */
    private String readFile(File file) throws IOException {
        try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
            final StringBuilder str = new StringBuilder((int) file.length());

            for (String line = reader.readLine(); line != null; line = reader.readLine()) {
                str.append(' ');
                str.append(line);
                str.append('\n');
            }
            return str.toString();
        }
    }

    /**
     * Verify the correct working of the locationTemp method
     *
     * @throws Exception
     */
    public void testLocationTemp() throws Exception {

        File testPom = new File(
                getBasedir(), "src/test/resources/unit/default-configuration/default-configuration-plugin-config.xml");
        PmdReport mojo = (PmdReport) lookupMojo("pmd", testPom);

        assertEquals(
                "locationTemp is not correctly encoding filename",
                "export_format_pmd_language_java_name_some_2520name.xml",
                mojo.getLocationTemp(
                        "http://nemo.sonarsource.org/sonar/profiles/export?format=pmd&language=java&name=some%2520name"));
    }

    /**
     * Verify that suppressMarker works
     *
     * @throws Exception
     */
    public void testSuppressMarkerConfiguration() throws Exception {
        File generatedReport = generateReport("pmd", "default-configuration/pmd-with-suppressMarker-plugin-config.xml");
        assertTrue(FileUtils.fileExists(generatedReport.getAbsolutePath()));

        // check if the PMD files were generated
        File generatedFile = new File(getBasedir(), "target/test/unit/default-configuration/target/pmd.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        String str = readFile(generatedFile);

        // check that there is no violation reported for "unusedVar2" - as it is suppressed
        assertFalse(str.contains("Avoid unused private fields such as 'unusedVar2'.\n </violation>"));
        // but it appears as suppressed
        assertTrue(str.contains("suppressiontype=\"nopmd\" msg=\"Avoid unused private fields such as 'unusedVar2'.\""));

        // check if there's a link to the JXR files
        str = readFile(generatedReport);

        assertTrue(str.contains("/xref/def/configuration/AppSample.html#L27"));
        // suppressed violation
        assertTrue(str.contains("Avoid unused private fields such as 'unusedVar2'."));
    }

    public void testSuppressMarkerConfigurationWithoutRendering() throws Exception {
        File generatedReport =
                generateReport("pmd", "default-configuration/pmd-with-suppressMarker-no-render-plugin-config.xml");
        assertTrue(FileUtils.fileExists(generatedReport.getAbsolutePath()));

        // check if the PMD files were generated
        File generatedFile = new File(getBasedir(), "target/test/unit/default-configuration/target/pmd.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        String str = readFile(generatedFile);

        // check that there is no violation reported for "unusedVar2" - as it is suppressed
        assertFalse(str.contains("Avoid unused private fields such as 'unusedVar2'.\n </violation>"));
        // but it appears as suppressed
        assertTrue(str.contains("suppressiontype=\"nopmd\" msg=\"Avoid unused private fields such as 'unusedVar2'.\""));

        // check if there's a link to the JXR files
        str = readFile(generatedReport);

        assertTrue(str.contains("/xref/def/configuration/AppSample.html#L27"));
        // suppressed violations are not rendered
        assertFalse(str.contains("Avoid unused private fields such as 'unusedVar2'."));
    }

    public void testJspConfiguration() throws Exception {
        File generatedReport = generateReport("pmd", "default-configuration/jsp-configuration-plugin-config.xml");
        assertTrue(FileUtils.fileExists(generatedReport.getAbsolutePath()));

        // check if the PMD files were generated
        File generatedFile = new File(getBasedir(), "target/test/unit/default-configuration/target/pmd.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        // these are the rulesets, that have been applied...
        generatedFile =
                new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/bestpractices.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        generatedFile =
                new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/codestyle.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        generatedFile = new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/design.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        generatedFile =
                new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/errorprone.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        generatedFile =
                new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/security.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        String str = readFile(generatedReport);
        assertTrue(str.contains("JSP file should use UTF-8 encoding"));
        assertTrue(str.contains("Using unsanitized JSP expression can lead to Cross Site Scripting (XSS) attacks"));
        assertTrue(str.contains("Avoid having style information in JSP files."));
    }

    public void testPMDProcessingError() throws Exception {
        try {
            generateReport("pmd", "processing-error/pmd-processing-error-plugin-config.xml");
            fail("Expected exception");
        } catch (RuntimeException e) {
            assertTrue(e.getMessage().endsWith("Found 1 PMD processing errors"));
        }
    }

    public void testPMDProcessingErrorWithDetailsSkipped() throws Exception {
        File generatedReport = generateReport("pmd", "processing-error/pmd-processing-error-skip-plugin-config.xml");
        assertTrue(FileUtils.fileExists(generatedReport.getAbsolutePath()));

        String output = CapturingPrintStream.getOutput();
        assertTrue(output.contains("There are 1 PMD processing errors:"));

        File generatedFile = new File(getBasedir(), "target/test/unit/parse-error/target/pmd.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));
        String str = readFile(generatedFile);
        assertTrue(str.contains("Error while parsing"));
        // The parse exception must be in the XML report
        assertTrue(str.contains("ParseException: Encountered \"\" at line 23, column 5."));

        str = readFile(generatedReport);
        // The parse exception must also be in the HTML report
        assertTrue(str.contains("ParseException: Encountered \"\" at line 23, column 5."));
    }

    public void testPMDProcessingErrorWithDetailsNoReport() throws Exception {
        File generatedReport =
                generateReport("pmd", "processing-error/pmd-processing-error-no-report-plugin-config.xml");
        assertTrue(FileUtils.fileExists(generatedReport.getAbsolutePath()));

        String output = CapturingPrintStream.getOutput();
        assertTrue(output.contains("There are 1 PMD processing errors:"));

        File generatedFile = new File(getBasedir(), "target/test/unit/parse-error/target/pmd.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));
        String str = readFile(generatedFile);
        assertTrue(str.contains("Error while parsing"));
        // The parse exception must be in the XML report
        assertTrue(str.contains("ParseException: Encountered \"\" at line 23, column 5."));

        str = readFile(generatedReport);
        // The parse exception must NOT be in the HTML report, since reportProcessingErrors is false
        assertFalse(str.contains("ParseException: Encountered \"\" at line 23, column 5."));
    }

    public void testPMDExcludeRootsShouldExcludeSubdirectories() throws Exception {
        generateReport("pmd", "exclude-roots/pmd-exclude-roots-plugin-config.xml");

        File generatedFile = new File(getBasedir(), "target/test/unit/exclude-roots/target/pmd.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));
        String str = readFile(generatedFile);

        assertTrue("Seems like all directories are excluded now", str.contains("ForLoopShouldBeWhileLoop"));
        assertFalse(
                "Exclusion of an exact source directory not working", str.contains("OverrideBothEqualsAndHashcode"));
        assertFalse(
                "Exclusion of basedirectory with subdirectories not working (MPMD-178)",
                str.contains("JumbledIncrementer"));
    }

    public void testViolationExclusion() throws Exception {
        generateReport("pmd", "default-configuration/pmd-report-pmd-exclusions-configuration-plugin-config.xml");

        File generatedFile = new File(getBasedir(), "target/test/unit/default-configuration/target/pmd.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));
        String str = readFile(generatedFile);

        assertEquals(0, StringUtils.countMatches(str, "<violation"));
    }

    public void testCustomRenderer() throws MavenReportException {
        final Renderer renderer = PmdExecutor.createRenderer("net.sourceforge.pmd.renderers.TextRenderer", "UTF-8");
        assertNotNull(renderer);
    }

    public void testCodeClimateRenderer() throws MavenReportException {
        final Renderer renderer =
                PmdExecutor.createRenderer("net.sourceforge.pmd.renderers.CodeClimateRenderer", "UTF-8");
        assertNotNull(renderer);
    }

    public void testPmdReportCustomRulesNoExternalInfoUrl() throws Exception {
        FileUtils.copyDirectoryStructure(
                new File(getBasedir(), "src/test/resources/unit/default-configuration/jxr-files"),
                new File(getBasedir(), "target/test/unit/default-configuration/target/site"));

        File generatedReport = generateReport("pmd", "default-configuration/pmd-report-custom-rules.xml");
        assertTrue(FileUtils.fileExists(generatedReport.getAbsolutePath()));

        String str = readFile(generatedReport);

        // custom rule without link
        assertEquals(2, StringUtils.countMatches(str, "<td align=\"left\">CustomRule</td>"));
        // standard rule with link
        assertEquals(4, StringUtils.countMatches(str, "\">UnusedPrivateField</a></td>"));
    }

    public void testPmdReportResolveRulesets() throws Exception {
        int port = determineFreePort();
        WireMockServer mockServer = new WireMockServer(port);
        mockServer.start();

        String sonarRuleset = IOUtils.toString(
                getClass()
                        .getClassLoader()
                        .getResourceAsStream("unit/default-configuration/rulesets/sonar-way-ruleset.xml"),
                StandardCharsets.UTF_8);

        final String sonarProfileUrl = "/profiles/export?format=pmd&language=java&name=Sonar%2520way";
        final String sonarExportRulesetUrl = "http://localhost:" + mockServer.port() + sonarProfileUrl;
        final String myRulesetBaseUrl = "/config/my-ruleset.xml";
        final String myRulesetUrl = "http://localhost:" + mockServer.port() + myRulesetBaseUrl;
        final String notAInternalRulesetBaseUrl =
                "/projects/OURPROJECT/repos/ourproject-pmd/raw/InProgressRuleset.xml?at=refs%2Fheads%2Fmaster";
        final String notAInternalRulesetUrl = "http://localhost:" + mockServer.port() + notAInternalRulesetBaseUrl;

        WireMock.configureFor("localhost", port);
        WireMock.stubFor(WireMock.get(WireMock.urlEqualTo(sonarProfileUrl))
                .willReturn(WireMock.aResponse()
                        .withStatus(200)
                        .withHeader("Content-Type", "text/xml")
                        .withBody(sonarRuleset)));
        WireMock.stubFor(WireMock.get(WireMock.urlEqualTo(myRulesetBaseUrl))
                .willReturn(WireMock.aResponse()
                        .withStatus(200)
                        .withHeader("Content-Type", "text/xml")
                        .withBody(sonarRuleset)));
        WireMock.stubFor(WireMock.get(WireMock.urlEqualTo(notAInternalRulesetBaseUrl))
                .willReturn(WireMock.aResponse()
                        .withStatus(200)
                        .withHeader("Content-Type", "text/xml")
                        .withBody(sonarRuleset)));

        FileUtils.copyDirectoryStructure(
                new File(getBasedir(), "src/test/resources/unit/default-configuration/jxr-files"),
                new File(getBasedir(), "target/test/unit/default-configuration/target/site"));

        File testPom =
                new File(getBasedir(), "src/test/resources/unit/default-configuration/pmd-report-resolve-rulesets.xml");
        PmdReport mojo = (PmdReport) createReportMojo("pmd", testPom);
        mojo.rulesets[3] = sonarExportRulesetUrl;
        mojo.rulesets[4] = myRulesetUrl;
        mojo.rulesets[5] = notAInternalRulesetUrl;
        generateReport(mojo, testPom);

        // these are the rulesets, that have been copied to target/pmd/rulesets
        File generatedFile =
                new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/custom-rules.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        generatedFile =
                new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/bestpractices.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        generatedFile =
                new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/java-design.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        generatedFile = new File(
                getBasedir(),
                "target/test/unit/default-configuration/target/pmd/rulesets/export_format_pmd_language_java_name_Sonar_2520way.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        generatedFile =
                new File(getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/my-ruleset.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        generatedFile = new File(
                getBasedir(),
                "target/test/unit/default-configuration/target/pmd/rulesets/InProgressRuleset.xml_at_refs_2Fheads_2Fmaster.xml");
        assertTrue(FileUtils.fileExists(generatedFile.getAbsolutePath()));

        mockServer.stop();
    }
}
