/*
 * 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.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;

import net.sourceforge.pmd.reporting.RuleViolation;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.pmd.model.Violation;

/**
 * This class contains utility for loading property files, which define which PMD violations
 * from which classes should be ignored and not cause a failure.
 * See property <code>pmd.excludeFromFailureFile</code>.
 *
 * @author Andreas Dangel
 */
public class ExcludeViolationsFromFile implements ExcludeFromFile<Violation> {
    private Map<String, Set<String>> excludeFromFailureClasses = new HashMap<>();

    @Override
    public void loadExcludeFromFailuresData(final String excludeFromFailureFile) throws MojoExecutionException {
        if (excludeFromFailureFile == null || excludeFromFailureFile.isEmpty()) {
            return;
        }

        File file = new File(excludeFromFailureFile);
        if (!file.exists()) {
            return;
        }
        final Properties props = new Properties();
        try (FileInputStream fileInputStream = new FileInputStream(new File(excludeFromFailureFile))) {
            props.load(fileInputStream);
        } catch (final IOException e) {
            throw new MojoExecutionException("Cannot load properties file " + excludeFromFailureFile, e);
        }
        for (final Entry<Object, Object> propEntry : props.entrySet()) {
            final Set<String> excludedRuleSet = new HashSet<>();
            final String className = propEntry.getKey().toString();
            final String[] excludedRules = propEntry.getValue().toString().split(",");
            for (final String excludedRule : excludedRules) {
                excludedRuleSet.add(excludedRule.trim());
            }
            excludeFromFailureClasses.put(className, excludedRuleSet);
        }
    }

    @Override
    public boolean isExcludedFromFailure(final Violation errorDetail) {
        final String className = extractClassName(
                errorDetail.getViolationPackage(), errorDetail.getViolationClass(), errorDetail.getFileName());
        return isExcludedFromFailure(className, errorDetail.getRule());
    }

    /**
     * Checks whether the given {@link RuleViolation} is excluded. Note: the exclusions must have been
     * loaded before via {@link #loadExcludeFromFailuresData(String)}.
     *
     * @param errorDetail the violation to check
     * @return <code>true</code> if the violation should be excluded, <code>false</code> otherwise.
     */
    public boolean isExcludedFromFailure(final RuleViolation errorDetail) {
        final Map<String, String> additionalInfo = errorDetail.getAdditionalInfo();
        final String className = extractClassName(
                additionalInfo.get(RuleViolation.PACKAGE_NAME),
                additionalInfo.get(RuleViolation.CLASS_NAME),
                errorDetail.getFileId().getAbsolutePath());
        return isExcludedFromFailure(className, errorDetail.getRule().getName());
    }

    @Override
    public int countExclusions() {
        int result = 0;
        for (Set<String> rules : excludeFromFailureClasses.values()) {
            result += rules.size();
        }
        return result;
    }

    private boolean isExcludedFromFailure(String className, String ruleName) {
        final Set<String> excludedRuleSet = excludeFromFailureClasses.get(className);
        return excludedRuleSet != null && excludedRuleSet.contains(ruleName);
    }

    private String extractClassName(String packageName, String className, String fullPath) {
        // for some reason, some violations don't contain the package name, so we have to guess the full class name
        // this looks like a bug in PMD - at least for UnusedImport rule.
        if (packageName != null && !packageName.isEmpty() && className != null && !className.isEmpty()) {
            return packageName + "." + className;
        } else if (packageName != null && !packageName.isEmpty()) {
            String fileName = fullPath;
            fileName = fileName.substring(fileName.lastIndexOf(File.separatorChar) + 1);
            fileName = fileName.substring(0, fileName.length() - 5);
            return packageName + "." + fileName;
        } else {
            final String fileName = fullPath;
            final int javaIdx = fileName.indexOf(File.separator + "java" + File.separator);
            return fileName.substring(javaIdx >= 0 ? javaIdx + 6 : 0, fileName.length() - 5)
                    .replace(File.separatorChar, '.');
        }
    }
}
