/****************************************************************
 * 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.james.jspf.parser;

import org.apache.james.jspf.core.SPF1Constants;
import org.apache.james.jspf.core.SPF1Record;
import org.apache.james.jspf.core.SPFRecordParser;
import org.apache.james.jspf.core.exceptions.NeutralException;
import org.apache.james.jspf.core.exceptions.NoneException;
import org.apache.james.jspf.core.exceptions.PermErrorException;
import org.apache.james.jspf.executor.FutureSPFResult;
import org.apache.james.jspf.terms.Configuration;
import org.apache.james.jspf.terms.Directive;
import org.apache.james.jspf.terms.Mechanism;
import org.apache.james.jspf.terms.Modifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * This class is used to parse SPF1-Records from their textual form to an
 * SPF1Record object that is composed by 2 collections: directives and
 * modifiers.
 * 
 * The parsing is modular and get informations from Mechanism and Modifiers
 * classes declared in the org/apache/james/jspf/parser/jspf.default.terms file.
 * 
 * Each term implementation provide its own REGEX in the REGEX static public
 * field. This parser simply join all the regexp in a single "alternative"
 * pattern and count the number of catch groups (brackets) assigned to each
 * regex fragment.
 * 
 * SO it creates a big regex and an array where it store what term is associated
 * to each catch group of the big regex.
 * 
 * If the regex matches the input vspf1 record then it start looking for the
 * matched group (not null) and lookup the term that created that part of the
 * regex.
 * 
 * With this informations it creates a new instance of the term and, if the term
 * is ConfigurationEnabled it calls the config() method passing to it only the specific
 * subset of the MatchResult (using the MatchResultSubset).
 * 
 * TODO doubts about the specification - redirect or exp with no domain-spec are
 * evaluated as an unknown-modifiers according to the current spec (it does not
 * make too much sense) - top-label is defined differently in various specs.
 * We'll have to review the code. -
 * http://data.iana.org/TLD/tlds-alpha-by-domain.txt (we should probably beeter
 * use and alpha sequence being at least 2 chars - Somewhere is defined as "."
 * TLD [ "." ] - Otherwise defined as ( *alphanum ALPHA *alphanum ) / (
 * 1*alphanum "-" *( * alphanum / "-" ) alphanum )
 * 
 * @see org.apache.james.jspf.core.SPF1Record
 * 
 */
public class RFC4408SPF1Parser implements SPFRecordParser {
    private static final Logger LOGGER = LoggerFactory.getLogger(RFC4408SPF1Parser.class);

    /**
     * Regex based on http://www.ietf.org/rfc/rfc4408.txt.
     * This will be the next official SPF-Spec
     */

    // Changed this because C, T and R MACRO_LETTERS are not available 
    // in record parsing and must return a PermError.
   
    // private static final String MACRO_LETTER_PATTERN = "[lsodipvhcrtLSODIPVHCRT]";

    /**
     * ABNF: qualifier = "+" / "-" / "?" / "~"
     */
    private static final String QUALIFIER_PATTERN = "[" + "\\"
            + SPF1Constants.PASS + "\\" + SPF1Constants.FAIL + "\\"
            + SPF1Constants.NEUTRAL + "\\" + SPF1Constants.SOFTFAIL + "]";

    private Pattern termsSeparatorPattern = null;

    private Pattern termPattern = null;

    private int TERM_STEP_REGEX_QUALIFIER_POS;

    private int TERM_STEP_REGEX_MECHANISM_POS;

    private int TERM_STEP_REGEX_MODIFIER_POS;

    private List<TermDefinition> matchResultPositions;

    private TermsFactory termsFactory;

    /**
     * Constructor. Creates all the values needed to run the parsing
     * 
     * @param termsFactory the TermsFactory implementation
     */
    public RFC4408SPF1Parser(TermsFactory termsFactory) {
        this.termsFactory = termsFactory;
        
        /**
         * ABNF: mechanism = ( all / include / A / MX / PTR / IP4 / IP6 / exists )
         */
        String MECHANISM_REGEX = createRegex(termsFactory.getMechanismsCollection());

        /**
         * ABNF: modifier = redirect / explanation / unknown-modifier
         */
        String MODIFIER_REGEX = "(" + createRegex(termsFactory.getModifiersCollection()) + ")";

        /**
         * ABNF: directive = [ qualifier ] mechanism
         */
        String DIRECTIVE_REGEX = "(" + QUALIFIER_PATTERN + "?)("
                + MECHANISM_REGEX + ")";

        /**
         * ABNF: ( directive / modifier )
         */
        String TERM_REGEX = "(?:" + MODIFIER_REGEX + "|" + DIRECTIVE_REGEX
                + ")";

        /**
         * ABNF: 1*SP
         */
        String TERMS_SEPARATOR_REGEX = "[ ]+";

        termsSeparatorPattern = Pattern.compile(TERMS_SEPARATOR_REGEX);
        termPattern = Pattern.compile(TERM_REGEX);

        initializePositions();
    }

    /**
     * Fill in the matchResultPositions ArrayList. This array simply map each
     * regex matchgroup to the Term class that originated that part of the
     * regex.
     */
    private void initializePositions() {
        ArrayList<TermDefinition> matchResultPositions = new ArrayList<TermDefinition>();

        // FULL MATCH
        int posIndex = 0;
        matchResultPositions.ensureCapacity(posIndex + 1);
        matchResultPositions.add(posIndex, null);

        Iterator<TermDefinition> i;

        TERM_STEP_REGEX_MODIFIER_POS = ++posIndex;
        matchResultPositions.ensureCapacity(posIndex + 1);
        matchResultPositions.add(TERM_STEP_REGEX_MODIFIER_POS, null);
        i = termsFactory.getModifiersCollection().iterator();
        while (i.hasNext()) {
            TermDefinition td = i.next();
            int size = td.getMatchSize() + 1;
            for (int k = 0; k < size; k++) {
                posIndex++;
                matchResultPositions.ensureCapacity(posIndex + 1);
                matchResultPositions.add(posIndex, td);
            }
        }

        TERM_STEP_REGEX_QUALIFIER_POS = ++posIndex;
        matchResultPositions.ensureCapacity(posIndex + 1);
        matchResultPositions.add(posIndex, null);

        TERM_STEP_REGEX_MECHANISM_POS = ++posIndex;
        matchResultPositions.ensureCapacity(posIndex + 1);
        matchResultPositions.add(TERM_STEP_REGEX_MECHANISM_POS, null);
        i = termsFactory.getMechanismsCollection().iterator();
        while (i.hasNext()) {
            TermDefinition td = i.next();
            int size = td.getMatchSize() + 1;
            for (int k = 0; k < size; k++) {
                posIndex++;
                matchResultPositions.ensureCapacity(posIndex + 1);
                matchResultPositions.add(posIndex, td);
            }
        }

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Parsing catch group positions: Modifiers[{}] Qualifier[{}] Mechanism[{}]",
                TERM_STEP_REGEX_MODIFIER_POS, TERM_STEP_REGEX_QUALIFIER_POS, TERM_STEP_REGEX_MECHANISM_POS);
            for (int k = 0; k < matchResultPositions.size(); k++) {
                LOGGER
                        .debug("{}) {}", k,
                            (matchResultPositions.get(k) != null ? ((TermDefinition) matchResultPositions
                                        .get(k)).getPattern().pattern()
                                        : null));
            }
        }
        
        this.matchResultPositions = Collections.synchronizedList(matchResultPositions);
    }

    /**
     * Loop the classes searching for a String static field named
     * staticFieldName and create an OR regeex like this:
     * (?:FIELD1|FIELD2|FIELD3)
     * 
     * @param classes
     *            classes to analyze
     * @param staticFieldName
     *            static field to concatenate
     * @return regex The regex
     */
    private String createRegex(Collection<TermDefinition> commandMap) {
        StringBuffer modifierRegex = new StringBuffer();
        Iterator<TermDefinition> i = commandMap.iterator();
        boolean first = true;
        while (i.hasNext()) {
            if (first) {
                modifierRegex.append("(?:(");
                first = false;
            } else {
                modifierRegex.append(")|(");
            }
            Pattern pattern = i.next().getPattern();
            modifierRegex.append(pattern.pattern());
        }
        modifierRegex.append("))");
        return modifierRegex.toString();
    }

    /**
     * @see org.apache.james.jspf.core.SPFRecordParser#parse(java.lang.String)
     */
    public SPF1Record parse(String spfRecord) throws PermErrorException,
            NoneException, NeutralException {

        LOGGER.debug("Start parsing SPF-Record: " + spfRecord);

        SPF1Record result = new SPF1Record();

        // check the version "header"
        if (spfRecord.toLowerCase().startsWith(SPF1Constants.SPF_VERSION1 + " ") || spfRecord.equalsIgnoreCase(SPF1Constants.SPF_VERSION1)) {
            if (!spfRecord.toLowerCase().startsWith(SPF1Constants.SPF_VERSION1 + " ")) throw new NeutralException("Empty SPF Record");
        } else {
            throw new NoneException("No valid SPF Record: " + spfRecord);
        }

        // extract terms
        String[] terms = termsSeparatorPattern.split(spfRecord.replaceFirst(
                SPF1Constants.SPF_VERSION1, ""));

        // cycle terms
        for (int i = 0; i < terms.length; i++) {
            if (terms[i].length() > 0) {
                Matcher termMatcher = termPattern.matcher(terms[i]);
                if (!termMatcher.matches()) {
                    throw new PermErrorException("Term [" + terms[i]
                            + "] is not syntactically valid: "
                            + termPattern.pattern());
                }

                // true if we matched a modifier, false if we matched a
                // directive
                String modifierString = termMatcher
                        .group(TERM_STEP_REGEX_MODIFIER_POS);

                if (modifierString != null) {
                    // MODIFIER
                    Modifier mod = (Modifier) lookupAndCreateTerm(termMatcher,
                            TERM_STEP_REGEX_MODIFIER_POS);

                    if (mod.enforceSingleInstance()) {
                        Iterator<Modifier> it = result.getModifiers().iterator();
                        while (it.hasNext()) {
                            if (it.next().getClass().equals(mod.getClass())) {
                                throw new PermErrorException("More than one "
                                        + modifierString
                                        + " found in SPF-Record");
                            }
                        }
                    }

                    result.getModifiers().add(mod);

                } else {
                    // DIRECTIVE
                    String qualifier = termMatcher
                            .group(TERM_STEP_REGEX_QUALIFIER_POS);

                    Object mech = lookupAndCreateTerm(termMatcher,
                            TERM_STEP_REGEX_MECHANISM_POS);

                    result.getDirectives().add(
                            new Directive(qualifier, (Mechanism) mech));

                }

            }
        }

        return result;
    }

    /**
     * @param res
     *            the MatchResult
     * @param start
     *            the position where the terms starts
     * @return
     * @throws PermErrorException
     */
    private Object lookupAndCreateTerm(Matcher res, int start)
            throws PermErrorException {
        for (int k = start + 1; k < res.groupCount(); k++) {
            if (res.group(k) != null && k != TERM_STEP_REGEX_QUALIFIER_POS) {
                TermDefinition c = (TermDefinition) matchResultPositions.get(k);
                Configuration subres = new MatcherBasedConfiguration(res, k, c
                        .getMatchSize());
                try {
                    return termsFactory.createTerm(c.getTermDef(), subres);
                } catch (InstantiationException e) {
                    e.printStackTrace();
                    // TODO is it ok to use a Runtime for this? Or should we use a PermError here?
                    throw new IllegalStateException("Unexpected error creating term: " + e.getMessage());
                }

            }
        }
        return null;
    }

}
