/*
 * Copyright (c) 2006, 2021 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 v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation
//
package org.eclipse.persistence.jpa.jpql.parser;

import org.eclipse.persistence.jpa.jpql.WordParser;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.*;

/**
 * This {@link JoinFactory} creates a new {@link Join} when the portion of the query to parse starts
 * with <b>JOIN</b> or <b>FETCH JOIN</b>, respectively.
 *
 * @see Join
 *
 * @version 2.5.2
 * @since 2.3
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public final class JoinFactory extends ExpressionFactory {

    /**
     * The unique identifier of this {@link JoinFactory}.
     */
    public static final String ID = JOIN;

    /**
     * Creates a new <code>JoinFactory</code>.
     */
    public JoinFactory() {
        super(ID, LEFT,
                  INNER,
                  JOIN,
                  OUTER,
                  FETCH);
    }

    @Override
    protected AbstractExpression buildExpression(AbstractExpression parent,
                                                 WordParser wordParser,
                                                 String word,
                                                 JPQLQueryBNF queryBNF,
                                                 AbstractExpression expression,
                                                 boolean tolerant) {

        int index = wordParser.position();

        // TODO: There must be a better way to parse all the JOIN identifiers with a generic
        //       parsing behavior without parsing something like "LEFT JOIN OUTER" has a single
        //       expression but multiple join expressions

        // JOIN and JOIN FETCH
        if (wordParser.startsWithIdentifier(JOIN, index)) {
            index += 4;
            index += wordParser.whitespaceCount(index);

            // JOIN FETCH
            if (wordParser.startsWithIdentifier(FETCH, index)) {
                expression = new Join(parent, JOIN_FETCH);
            }
            // JOIN
            else {
                expression = new Join(parent, JOIN);
            }
        }
        // LEFT
        else if (wordParser.startsWithIdentifier(LEFT)) {
            index += 4;
            index += wordParser.whitespaceCount(index);

            // LEFT OUTER
            if (wordParser.startsWithIdentifier(OUTER, index)) {
                index += 5;
                index += wordParser.whitespaceCount(index);

                if (wordParser.startsWithIdentifier(JOIN, index)) {
                    index += 4;
                    index += wordParser.whitespaceCount(index);

                    // LEFT OUTER JOIN FETCH
                    if (wordParser.startsWithIdentifier(FETCH, index)) {
                        expression = new Join(parent, LEFT_OUTER_JOIN_FETCH);
                    }
                    // LEFT OUTER JOIN
                    else {
                        expression = new Join(parent, LEFT_OUTER_JOIN);
                    }
                }
                // LEFT OUTER INNER
                else if (wordParser.startsWithIdentifier(INNER, index)) {
                    index += 5;
                    index += wordParser.whitespaceCount(index);

                    if (wordParser.startsWithIdentifier(JOIN, index)) {
                        index += 4;
                        index += wordParser.whitespaceCount(index);

                        // LEFT OUTER INNER JOIN FETCH
                        if (wordParser.startsWithIdentifier(FETCH, index)) {
                            expression = new Join(parent, "LEFT OUTER INNER JOIN FETCH");
                        }
                        // LEFT OUTER INNER JOIN
                        else {
                            expression = new Join(parent, "LEFT OUTER INNER JOIN");
                        }
                    }
                    else {
                        expression = new Join(parent, "LEFT OUTER INNER");
                    }
                }
                else {
                    expression = new Join(parent, "LEFT OUTER");
                }
            }
            // LEFT JOIN
            else if (wordParser.startsWithIdentifier(JOIN, index)) {
                index += 4;
                index += wordParser.whitespaceCount(index);

                // LEFT JOIN FETCH
                if (wordParser.startsWithIdentifier(FETCH, index)) {
                    expression = new Join(parent, LEFT_JOIN_FETCH);
                }
                // LEFT JOIN
                else {
                    expression = new Join(parent, LEFT_JOIN);
                }
            }
            // LEFT INNER
            else if (wordParser.startsWithIdentifier(INNER, index)) {
                index += 5;
                index += wordParser.whitespaceCount(index);

                // LEFT INNER JOIN
                if (wordParser.startsWithIdentifier(JOIN, index)) {
                    index += 5;
                    index += wordParser.whitespaceCount(index);

                    // LEFT INNER JOIN FETCH
                    if (wordParser.startsWithIdentifier(FETCH, index)) {
                        expression = new Join(parent, "LEFT INNER JOIN FETCH");
                    }
                    // LEFT INNER JOIN
                    else {
                        expression = new Join(parent, "LEFT INNER JOIN");
                    }
                }
            }
            // LEFT
            else {
                expression = new Join(parent, LEFT);
            }
        }
        // INNER JOIN and INNER JOIN FETCH
        else if (wordParser.startsWithIdentifier(INNER, index)) {
            index += 5;
            index += wordParser.whitespaceCount(index);

            if (wordParser.startsWithIdentifier(JOIN, index)) {
                index += 4;
                index += wordParser.whitespaceCount(index);

                // INNER JOIN FETCH
                if (wordParser.startsWithIdentifier(FETCH, index)) {
                    expression = new Join(parent, INNER_JOIN_FETCH);
                }
                // INNER JOIN
                else {
                    expression = new Join(parent, INNER_JOIN);
                }
            }
            // INNER
            else {
                expression = new Join(parent, INNER);
            }
        }
        // OUTER JOIN and OUTER JOIN FETCH
        // OUTER INNER JOIN and OUTER INNER JOIN FETCH
        else if (wordParser.startsWithIdentifier(OUTER, index)) {
            index += 5;
            index += wordParser.whitespaceCount(index);

            // OUTER JOIN and OUTER JOIN FETCH
            if (wordParser.startsWithIdentifier(JOIN, index)) {
                index += 4;
                index += wordParser.whitespaceCount(index);

                // OUTER JOIN FETCH
                if (wordParser.startsWithIdentifier(FETCH, index)) {
                    expression = new Join(parent, "OUTER JOIN FETCH");
                }
                // OUTER JOIN
                else {
                    expression = new Join(parent, "OUTER JOIN");
                }
            }
            // OUTER INNER JOIN and OUTER INNER JOIN FETCH
            else if (wordParser.startsWithIdentifier(INNER, index)) {
                index += 5;
                index += wordParser.whitespaceCount(index);

                if (wordParser.startsWithIdentifier(JOIN, index)) {
                    index += 4;
                    index += wordParser.whitespaceCount(index);

                    // OUTER INNER JOIN FETCH
                    if (wordParser.startsWithIdentifier(FETCH, index)) {
                        expression = new Join(parent, "OUTER INNER JOIN FETCH");
                    }
                    // INNER JOIN
                    else {
                        expression = new Join(parent, "OUTER INNER JOIN");
                    }
                }
            }
            // OUTER
            else {
                expression = new Join(parent, OUTER);
            }
        }
        else {
            return null;
        }

        expression.parse(wordParser, tolerant);
        return expression;
    }
}
