// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.testing.local;

import org.junit.runner.Description;
import org.junit.runner.manipulation.Filter;

import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *  Filters tests based on a googletest-style filter string.
 */
class GtestFilter extends Filter {

    private final String mFilterString;

    private final Set<Pattern> mPositiveRegexes;
    private final Set<Pattern> mNegativeRegexes;

    private static final Pattern ASTERISK = Pattern.compile("\\*");
    private static final Pattern COLON = Pattern.compile(":");
    private static final Pattern DASH = Pattern.compile("-");
    private static final Pattern DOLLAR = Pattern.compile("\\$");
    private static final Pattern PERIOD = Pattern.compile("\\.");

    /**
     *  Creates the filter and converts the provided googletest-style filter
     *  string into positive and negative regexes.
     */
    public GtestFilter(String filterString) {
        mFilterString = filterString;

        String[] filterStrings = DASH.split(filterString, 2);
        mPositiveRegexes = generatePatternSet(filterStrings[0]);
        if (filterStrings.length == 2) {
            mNegativeRegexes = generatePatternSet(filterStrings[1]);
        } else {
            mNegativeRegexes = new HashSet<Pattern>();
        }
    }

    private Set<Pattern> generatePatternSet(String filterString) {
        Set<Pattern> patterns = new HashSet<Pattern>();
        String[] filterStrings = COLON.split(filterString);
        for (String f : filterStrings) {
            if (f.isEmpty()) continue;

            String sanitized = PERIOD.matcher(f).replaceAll(Matcher.quoteReplacement("\\."));
            sanitized = DOLLAR.matcher(sanitized).replaceAll(Matcher.quoteReplacement("\\$"));
            sanitized = ASTERISK.matcher(sanitized).replaceAll(".*");
            patterns.add(Pattern.compile(sanitized));
        }
        return patterns;
    }

    /**
     *  Determines whether or not a test with the provided description should
     *  run based on the configured positive and negative regexes.
     *
     *  A test should run if:
     *    - it's just a class, OR
     *    - it doesn't match any of the negative regexes, AND
     *    - either:
     *      - there are no configured positive regexes, OR
     *      - it matches at least one of the positive regexes.
     */
    @Override
    public boolean shouldRun(Description description) {
        if (description.getMethodName() == null) return true;

        String gtestName = description.getClassName() + "." + description.getMethodName();
        for (Pattern p : mNegativeRegexes) {
            if (p.matcher(gtestName).matches()) return false;
        }

        if (mPositiveRegexes.isEmpty()) return true;

        for (Pattern p : mPositiveRegexes) {
            if (p.matcher(gtestName).matches()) return true;
        }

        return false;
    }

    /**
     *  Returns a description of this filter.
     */
    @Override
    public String describe() {
        return "gtest-filter: " + mFilterString;
    }

}

