/*
 * 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.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 String className =
                extractClassName(errorDetail.getPackageName(), errorDetail.getClassName(), errorDetail.getFilename());
        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, '.');
        }
    }
}
