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

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.jsieve.exception.SieveException;
import org.apache.jsieve.exception.StopException;
import org.apache.jsieve.mail.ActionKeep;
import org.apache.jsieve.mail.MailAdapter;
import org.apache.jsieve.parser.generated.Node;
import org.apache.jsieve.parser.generated.ParseException;
import org.apache.jsieve.parser.generated.SieveParser;
import org.apache.jsieve.parser.generated.SieveParserVisitor;
import org.apache.jsieve.parser.generated.SimpleNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>
 * SieveFactory is the primary invocation point for all Sieve
 * operations. These are...
 * <dl>
 * <dt>{@link #parse(InputStream)}</dt>
 * <dd> Parse a Sieve script into a hierarchy of parsed nodes. A succesful parse
 * means the script is lexically and gramatically valid according to RFC 3028,
 * section 8. The result is the start node of the parsed Sieve script. The start
 * node is resuable. Typically it is stored for reuse in all subsequent
 * evaluations of the script. </dd>
 * <dt>{@link #evaluate(MailAdapter, Node)}</dt>
 * <dd> Evaluate an RFC 822 compliant mail message wrapped in a {@link MailAdapter}
 * against the parse result referenced by the start node from the Parse
 * operation above. As evaluation proceeds a List of {@link org.apache.jsieve.mail.Action}s 
 * is added to the MailAdapter. At the end of evaluation, each Action in the List is executed in
 * the order they were added. </dd>
 * <dt>{@link #interpret(MailAdapter, InputStream)}</dt>
 * <dd>A concatenation of parse and evaluate. Useful for testing, but generally
 * the parse result should be stored for reuse in subsequent evaluations. </dd>
 * </dl>
 * </p>
 * <h4>Thread Safety</h4>
 * <p>
 * An instance can be safely accessed concurrently by multiple threads
 * provided that the managers used to construct the instance 
 * (when {@link #SieveFactory(CommandManager, ComparatorManager, TestManager, Log)} 
 * is called) are thread safe.
 * </p>
 */
public class SieveFactory {
    private static final Logger LOGGER = LoggerFactory.getLogger(SieveFactory.class);

    private final CommandManager commandManager;

    private final ComparatorManager comparatorManager;

    private final TestManager testManager;

    /**
     * Constructor for SieveFactory.
     */
    public SieveFactory(final CommandManager commandManager,
            final ComparatorManager comparatorManager,
            final TestManager testManager) {
        super();
        this.commandManager = commandManager;
        this.comparatorManager = comparatorManager;
        this.testManager = testManager;
    }

    /**
     * Method parse parses a Sieve script into a hierarchy of parsed nodes. A
     * successful parse means the script is lexically and grammatically valid
     * according to RFC 3028, section 8. The result is the start node of the
     * parsed Sieve script. The start node is reusable. Typically it is stored
     * for reuse in subsequent evaluations of the script.
     * 
     * @param inputStream
     * @return Node
     * @throws ParseException
     */
    public Node parse(InputStream inputStream) throws ParseException {
        try {
            final SimpleNode node = new SieveParser(inputStream, "UTF-8")
                    .start();
            SieveValidationVisitor visitor = new SieveValidationVisitor(
                    commandManager, testManager, comparatorManager);
            node.jjtAccept(visitor, null);
            return node;
        } catch (ParseException ex) {
            LOGGER.error("Parse failed.", ex);
            throw ex;
        } catch (SieveException ex) {
            LOGGER.error("Parse failed.", ex);
            throw new ParseException(ex.getMessage());
        }
    }

    /**
     * <p>
     * Method evaluate evaluates an RFC 822 compliant mail message wrapped in a
     * MailAdapter by visting each node of the parsed script beginning at the
     * passed start node. As evaluation proceeds a List of Actions is added to
     * the MailAdapter.
     * <p>
     * 
     * <p>
     * At the start of evaluation an 'implicitKeep' state is set. This can be
     * cancelled by a Command during evaluation. If 'implicitKeep' is still set
     * at the end of evaluation, a Keep Action is added to the List of Actions.
     * Finally, each Action in the List is executed in the order they were
     * added.
     * </p>
     * 
     * @param mail
     * @param startNode
     * @throws SieveException
     */
    public void evaluate(MailAdapter mail, Node startNode)
            throws SieveException {
        final SieveContext context = new BaseSieveContext(commandManager,
                comparatorManager, testManager);
        try {
            // Ensure that the context is set on the mail
            mail.setContext(context);
            
            SieveParserVisitor visitor = new SieveParserVisitorImpl(context);
            try {
                // Evaluate the Nodes
                startNode.jjtAccept(visitor, mail);
    
            } catch (StopException ex) {
                // Stop is OK
            } catch (SieveException ex) {
                LOGGER.error("Evaluation failed.", ex);
                throw ex;
            }
    
            // If after evaluating all of the nodes or stopping, implicitKeep is
            // still
            // in effect, add a Keep to the list of Actions.
            if (context.getCommandStateManager().isImplicitKeep())
                mail.addAction(new ActionKeep());
    
            // Execute the List of Actions
            try {
                mail.executeActions();
            } catch (SieveException ex) {
                LOGGER.error("Evaluation failed.", ex);
                throw ex;
            }
        } finally {
            // Tidy up by ensuring that a reference to the context is not held by the adapter.
            // This prevents leaks when the adapter stores the context in a thread local variable.
            mail.setContext(null);
        }
    }

    /**
     * Method interpret parses a Sieve script and then evaluates the result
     * against a mail.
     * 
     * @param mail
     * @param inputStream
     * @throws ParseException
     * @throws SieveException
     */
    public void interpret(MailAdapter mail, InputStream inputStream)
            throws ParseException, SieveException {
        evaluate(mail, parse(inputStream));
    }
    
    /**
     * <p>Answer a List of supported Sieve extensions. This depends on the configured Command, Comparator
     * and Test managers.
     *
     * @return a List of supported Sieve extensions
     */
    public List<String> getExtensions() {
        List<String> commands = commandManager.getExtensions();
        List<String> comparators = comparatorManager.getExtensions();
        List<String> tests = testManager.getExtensions();
        List<String> extensions = new ArrayList<String>(commands.size() + comparators.size()
                + tests.size());
        extensions.addAll(commands);
        extensions.addAll(comparators);
        extensions.addAll(tests);
        return extensions;
    }
}
