/*******************************************************************************
 * Copyright (c) 1998, 2016 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
 * which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/
package org.eclipse.persistence.internal.jpa.parsing.jpql;

import java.util.ArrayList;
import java.util.List;

//toplink imports
import org.eclipse.persistence.exceptions.JPQLException;
import org.eclipse.persistence.internal.jpa.parsing.JPQLParseTree;
import org.eclipse.persistence.internal.jpa.parsing.NodeFactory;
import org.eclipse.persistence.internal.jpa.parsing.NodeFactoryImpl;
import org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParserBuilder;
// Third party (ANLTR) stuff
import org.eclipse.persistence.internal.libraries.antlr.runtime.MismatchedTokenException;
import org.eclipse.persistence.internal.libraries.antlr.runtime.NoViableAltException;
import org.eclipse.persistence.internal.libraries.antlr.runtime.RecognitionException;
import org.eclipse.persistence.internal.libraries.antlr.runtime.RecognizerSharedState;
import org.eclipse.persistence.internal.libraries.antlr.runtime.Token;
import org.eclipse.persistence.internal.libraries.antlr.runtime.TokenStream;

/**
 * EJBQLParser is the superclass of the ANTLR generated parser.
 */
public abstract class JPQLParser extends org.eclipse.persistence.internal.libraries.antlr.runtime.Parser {

    /** List of errors. */
    private List errors = new ArrayList();

    /** The name of the query being compiled.
     *  The variable is null for dynamic queries.
     */
    private String queryName = null;

    /** The text of the query being compiled. */
    private String queryText = null;

    /** The factory to create parse tree nodes. */
    protected NodeFactory factory;

    protected JPQLParser(TokenStream stream) {
        super(stream);
    }

    public JPQLParser(TokenStream input, RecognizerSharedState state) {
        super(input, state);
    }

    /**
     * INTERNAL
     * Returns the ANTLR version currently used.
     */
    public static String ANTLRVersion() throws Exception {
        return "3.5.2";
    }

    /**
     * INTERNAL
     * Builds a parser, parses the specified query string and returns the
     * parse tree. Any error in the query text results in an JPQLException.
     * This method is used for dynamic queries.
     */
    public static JPQLParseTree buildParseTree(String queryText)
        throws JPQLException {
        return buildParseTree(null, queryText);
    }

    /**
     * INTERNAL
     * Builds a parser, parses the specified query string and returns the
     * parse tree. Any error in the query text results in an JPQLException.
     */
    public static JPQLParseTree buildParseTree(String queryName, String queryText)
        throws JPQLException {
        JPQLParser parser = buildParserFor(queryName, queryText);
        return parser.parse();
    }

    /**
     * INTERNAL
     * Creates a parser for the specified query string. The query string is
     * not parsed (see method parse).
     * This method is used for dynamic queries.
     */
    public static JPQLParser buildParserFor(String queryText)
        throws JPQLException {
        return buildParserFor(null, queryText);
    }

    /**
     * INTERNAL
     * Creates a parser for the specified query string. The query string is
     * not parsed (see method parse).
     */
    public static JPQLParser buildParserFor(String queryName, String queryText)
        throws JPQLException {
        try {
            JPQLParser parser = JPQLParserBuilder.buildParser(queryText);
            parser.setQueryName(queryName);
            parser.setQueryText(queryText);
            parser.setNodeFactory(new NodeFactoryImpl(parser.getQueryInfo()));
            return parser;
        } catch (Exception ex) {
            throw JPQLException.generalParsingException(queryText, ex);
        }
    }

    /**
     * INTERNAL
     * Parse the query string that was specified on parser creation.
     */
    public JPQLParseTree parse()
        throws JPQLException {
        try {
            document();
        } catch (Exception e) {
            addError(e);
        }

        // Handle any errors generated by the Parser
        if (hasErrors()) {
            throw generateException();
        }

        // return the parser tree
        return getParseTree();
    }

    /**
     * INTERNAL
     * Returns the parse tree created by a successful run of the parse
     * method.
     */
    public JPQLParseTree getParseTree() {
        return (JPQLParseTree)getRootNode();
    }

    /**
     * INTERNAL
     * Return the text of the current query being compiled.
     */
    public String getQueryText() {
        return queryText;
    }

    /**
     * INTERNAL
     * Set the text of the current query being compiled.
     * Please note, setting the query text using this method is for error
     * handling and debugging purposes.
     */
    public void setQueryText(String queryText) {
        this.queryText = queryText;
    }

    /**
     * INTERNAL
     * Return the name of the current query being compiled. This method returns
     * <code>null</code> if the current query is a dynamic query and not a named
     * query.
     */
    public String getQueryName() {
        return queryText;
    }

    /**
     * INTERNAL
     * Set the name of the current query being compiled.
     * Please note, setting the query name using this method is for error
     * handling and debugging purposes.
     */
    public void setQueryName(String queryName) {
        this.queryName = queryName;
    }

    /**
     * INTERNAL
     * Return the the query text prefixed by the query name in case of a
     * named query. The method returns just the query text in case of a dynamic
     * query.
     */
    public String getQueryInfo() {
        return (queryName == null) ? queryText :
            queryName + ": " + queryText;
    }

    /**
     * INTERNAL
     * Set the factory used by the parser to create a parse tree and parse
     * tree nodes.
     */
    public void setNodeFactory(NodeFactory factory) {
        this.factory = factory;
    }

    /**
     * INTERNAL
     * Returns the factory used by the parser to create a parse tree and parse
     * tree nodes.
     */
    public NodeFactory getNodeFactory() {
        return factory;
    }

    /**
     * INTERNAL
     * Returns the list of errors found during the parsing process.
     */
    public List getErrors() {
        return errors;
    }

    /**
     * INTERNAL
     * Returns true if there were errors during the parsing process.
     */
    public boolean hasErrors() {
        return !getErrors().isEmpty();
    }

    /**
     * INTERNAL
     * Add the exception to the list of errors.
     */
    public void addError(Exception e) {
        if (e instanceof RecognitionException) {
            e = handleRecognitionException((RecognitionException)e);
        } else if (!(e instanceof JPQLException)) {
            e = JPQLException.generalParsingException(getQueryInfo(), e);
        }
        errors.add(e);
    }

    /**
     * INTERNAL
     * Generate an exception which encapsulates all the exceptions generated
     * by this parser. Special case where the first exception is an
     * JPQLException.
     */
    protected JPQLException generateException() {
        //Handle exceptions we expect (such as expressionSotSupported)
        Exception firstException = (Exception)getErrors().get(0);
        if (firstException instanceof JPQLException) {
            return (JPQLException)firstException;
        }

        //Handle general exceptions, such as NPE
        JPQLException exception =
            JPQLException.generalParsingException(getQueryInfo());
        exception.setInternalExceptions(getErrors());
        return exception;
    }

    /**
     * INTERNAL
     * Map an exception thrown by the ANTLR generated code to an
     * JPQLException.
     */
    //gf1166 Wrap ANTLRException inside JPQLException
    protected JPQLException handleRecognitionException(RecognitionException ex) {
        JPQLException result = null;
        // TODO: figure out the equivalent
       /* if (ex instanceof MismatchedCharException) {
            MismatchedCharException mismatched = (MismatchedCharException)ex;
            if (mismatched.foundChar == EOF_CHAR) {
                result = JPQLException.unexpectedEOF(getQueryInfo(),
                    mismatched.getLine(), mismatched.getColumn(), ex);
            } else if (mismatched.mismatchType == MismatchedCharException.CHAR) {
                result = JPQLException.expectedCharFound(getQueryInfo(),
                    mismatched.getLine(), mismatched.getColumn(),
                    String.valueOf((char)mismatched.expecting),
                    String.valueOf((char)mismatched.foundChar),
                    ex);
            }
        }
        else*/
        if (ex instanceof MismatchedTokenException) {
            MismatchedTokenException mismatched = (MismatchedTokenException)ex;
            Token token = mismatched.token;
            if (token != null) {
                if (token.getType() == Token.EOF) {
                    result = JPQLException.unexpectedEOF(getQueryInfo(),
                        mismatched.line, mismatched.charPositionInLine, ex);
                }
                else {
                    result = JPQLException.syntaxErrorAt(getQueryInfo(),
                        mismatched.line, mismatched.charPositionInLine,
                        token.getText(), ex);
                }
            }
        }
        else if (ex instanceof NoViableAltException) {
            NoViableAltException noviable = (NoViableAltException)ex;
            Token token = noviable.token;
            if (token != null) {
                if (token.getType() == Token.EOF) {
                    result = JPQLException.unexpectedEOF(getQueryInfo(),
                        noviable.line, noviable.charPositionInLine, ex);
                }
                else {
                    result = JPQLException.unexpectedToken(getQueryInfo(),
                        noviable.line, noviable.charPositionInLine,
                        token.getText(), ex);
                }
            }
        } else if (ex instanceof InvalidIdentifierException){
            InvalidIdentifierException invalid = (InvalidIdentifierException)ex;
            Token token = invalid.getToken();
            if (token != null) {
                if (token.getType() == Token.EOF) {
                    result = JPQLException.unexpectedEOF(getQueryInfo(),
                            token.getLine(), token.getCharPositionInLine(), ex);
                }
                else {
                    result = JPQLException.unexpectedToken(getQueryInfo(),
                            token.getLine(), token.getCharPositionInLine(),
                        token.getText(), ex);
                }
            }
        } else if (ex instanceof InvalidIdentifierStartException) {
            InvalidIdentifierStartException invalid = (InvalidIdentifierStartException)ex;
            result = JPQLException.unexpectedChar(getQueryInfo(),
                    invalid.line, invalid.charPositionInLine,
                String.valueOf((char)invalid.c), ex);
        }
        /*
        else if (ex instanceof TokenStreamRecognitionException) {
            result = handleANTLRException(((TokenStreamRecognitionException)ex).recog);
        }*/


        if (result == null) {
            // no special handling from aboves matches the exception if this
            // line is reached => make it a syntax error
            result = JPQLException.syntaxError(getQueryInfo(), ex);
        }
        return result;
    }

    /**
     * Method called by the ANTLR generated code in case of an error.
     */
    @Override
    public void reportError(RecognitionException ex) {
        addError(ex);
    }

    /**
     * This is the parser start method. It will be implemented by the ANTLR
     * generated subclass.
     */
    public abstract void document() throws RecognitionException;

    /**
     * Returns the root node after representing the parse tree for the current
     * query string. It will be implemented by the ANTLR generated subclass.
     */
    public abstract Object getRootNode();

}
