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

import java.util.List;

import org.apache.metamodel.schema.Column;
import org.apache.metamodel.schema.ColumnType;
import org.apache.metamodel.schema.Schema;
import org.apache.metamodel.schema.Table;
import org.apache.metamodel.util.BaseObject;
import org.apache.metamodel.util.EqualsBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Represents a SELECT item. SelectItems can take different forms:
 * <ul>
 * <li>column SELECTs (selects a column from a table)</li>
 * <li>column function SELECTs (aggregates the values of a column)</li>
 * <li>expression SELECTs (retrieves data based on an expression (only supported
 * for JDBC datastores)</li>
 * <li>expression function SELECTs (retrieves databased on a function and an
 * expression, only COUNT(*) is supported for non-JDBC datastores))</li>
 * <li>SELECTs from subqueries (works just like column selects, but in stead of
 * pointing to a column, it retrieves data from the select item of a subquery)
 * </li>
 * </ul>
 * 
 * @see SelectClause
 */
public class SelectItem extends BaseObject implements QueryItem, Cloneable {

    public static final String FUNCTION_APPROXIMATION_PREFIX = "APPROXIMATE ";

    private static final long serialVersionUID = 317475105509663973L;
    private static final Logger logger = LoggerFactory.getLogger(SelectItem.class);

    // immutable fields (essense)
    private final Column _column;
    private final FunctionType _function;
    private final String _expression;
    private final SelectItem _subQuerySelectItem;
    private final FromItem _fromItem;

    // mutable fields (tweaking)
    private boolean _functionApproximationAllowed;
    private Query _query;
    private String _alias;

    /**
     * All-arguments constructor
     * 
     * @param column
     * @param fromItem
     * @param function
     * @param expression
     * @param subQuerySelectItem
     * @param alias
     * @param functionApproximationAllowed
     */
    private SelectItem(Column column, FromItem fromItem, FunctionType function, String expression,
            SelectItem subQuerySelectItem, String alias, boolean functionApproximationAllowed) {
        super();
        _column = column;
        _fromItem = fromItem;
        _function = function;
        _expression = expression;
        _subQuerySelectItem = subQuerySelectItem;
        _alias = alias;
        _functionApproximationAllowed = functionApproximationAllowed;
    }

    /**
     * Generates a COUNT(*) select item
     */
    public static SelectItem getCountAllItem() {
        return new SelectItem(FunctionType.COUNT, "*", null);
    }

    public static boolean isCountAllItem(SelectItem item) {
        if (item != null && item.getFunction() != null && item.getFunction().toString().equals("COUNT")
                && item.getExpression() == "*") {
            return true;
        }
        return false;
    }

    /**
     * Creates a simple SelectItem that selects from a column
     * 
     * @param column
     */
    public SelectItem(Column column) {
        this(null, column);
    }

    /**
     * Creates a SelectItem that uses a function on a column, for example
     * SUM(price) or MAX(age)
     * 
     * @param function
     * @param column
     */
    public SelectItem(FunctionType function, Column column) {
        this(function, column, null);
    }

    /**
     * Creates a SelectItem that references a column from a particular
     * {@link FromItem}, for example a.price or p.age
     * 
     * @param column
     * @param fromItem
     */
    public SelectItem(Column column, FromItem fromItem) {
        this(null, column, fromItem);
        if (fromItem != null) {
            Table fromItemTable = fromItem.getTable();
            if (fromItemTable != null) {
                Table columnTable = column.getTable();
                if (columnTable != null && !columnTable.equals(fromItemTable)) {
                    throw new IllegalArgumentException("Column's table '" + columnTable.getName()
                            + "' is not equal to referenced table: " + fromItemTable);
                }
            }
        }
    }

    /**
     * Creates a SelectItem that uses a function on a column from a particular
     * {@link FromItem}, for example SUM(a.price) or MAX(p.age)
     * 
     * @param function
     * @param column
     * @param fromItem
     */
    public SelectItem(FunctionType function, Column column, FromItem fromItem) {
        this(column, fromItem, function, null, null, null, false);
        if (column == null) {
            throw new IllegalArgumentException("column=null");
        }
    }

    /**
     * Creates a SelectItem based on an expression. All expression-based
     * SelectItems must have aliases.
     * 
     * @param expression
     * @param alias
     */
    public SelectItem(String expression, String alias) {
        this(null, expression, alias);
    }

    /**
     * Creates a SelectItem based on a function and an expression. All
     * expression-based SelectItems must have aliases.
     * 
     * @param function
     * @param expression
     * @param alias
     */
    public SelectItem(FunctionType function, String expression, String alias) {
        this(null, null, function, expression, null, alias, false);
        if (expression == null) {
            throw new IllegalArgumentException("expression=null");
        }
    }

    /**
     * Creates a SelectItem that references another select item in a subquery
     * 
     * @param subQuerySelectItem
     * @param subQueryFromItem
     *            the FromItem that holds the sub-query
     */
    public SelectItem(SelectItem subQuerySelectItem, FromItem subQueryFromItem) {
        this(null, subQueryFromItem, null, null, subQuerySelectItem, null, false);
        if (subQueryFromItem.getSubQuery() == null) {
            throw new IllegalArgumentException("Only sub-query based FromItems allowed.");
        }
        if (subQuerySelectItem.getQuery() != null
                && !subQuerySelectItem.getQuery().equals(subQueryFromItem.getSubQuery())) {
            throw new IllegalArgumentException("The SelectItem must exist in the sub-query");
        }
    }

    public String getAlias() {
        return _alias;
    }

    public SelectItem setAlias(String alias) {
        _alias = alias;
        return this;
    }

    /**
     * 
     * @return
     * @deprecated use {@link #getAggregateFunction()} or
     *             {@link #getScalarFunction()} instead
     */
    @Deprecated
    public FunctionType getFunction() {
        return _function;
    }

    public AggregateFunction getAggregateFunction() {
        if (_function instanceof AggregateFunction) {
            return (AggregateFunction) _function;
        }
        return null;
    }

    public ScalarFunction getScalarFunction() {
        if (_function instanceof ScalarFunction) {
            return (ScalarFunction) _function;
        }
        return null;
    }

    /**
     * @return if this is a function based SelectItem where function calculation
     *         is allowed to be approximated (if the datastore type has an
     *         approximate calculation method). Approximated function results
     *         are as the name implies not exact, but might be valuable as an
     *         optimization in some cases.
     */
    public boolean isFunctionApproximationAllowed() {
        return _functionApproximationAllowed;
    }

    public void setFunctionApproximationAllowed(boolean functionApproximationAllowed) {
        _functionApproximationAllowed = functionApproximationAllowed;
    }

    public Column getColumn() {
        return _column;
    }

    /**
     * Tries to infer the {@link ColumnType} of this {@link SelectItem}. For
     * expression based select items, this is not possible, and the method will
     * return null.
     * 
     * @return
     */
    public ColumnType getExpectedColumnType() {
        if (_subQuerySelectItem != null) {
            return _subQuerySelectItem.getExpectedColumnType();
        }
        if (_function != null) {
            if (_column != null) {
                return _function.getExpectedColumnType(_column.getType());
            } else {
                return _function.getExpectedColumnType(null);
            }
        }
        if (_column != null) {
            return _column.getType();
        }
        return null;
    }

    public String getExpression() {
        return _expression;
    }

    public SelectItem setQuery(Query query) {
        _query = query;
        return this;
    }

    public Query getQuery() {
        return _query;
    }

    public SelectItem getSubQuerySelectItem() {
        return _subQuerySelectItem;
    }

    /**
     * @deprecated use {@link #getFromItem()} instead
     */
    @Deprecated
    public FromItem getSubQueryFromItem() {
        return _fromItem;
    }

    public FromItem getFromItem() {
        return _fromItem;
    }

    /**
     * @return the name that this SelectItem can be referenced with, if
     *         referenced from a super-query. This will usually be the alias,
     *         but if there is no alias, then the column name will be used.
     */
    public String getSuperQueryAlias() {
        return getSuperQueryAlias(true);
    }

    /**
     * @return the name that this SelectItem can be referenced with, if
     *         referenced from a super-query. This will usually be the alias,
     *         but if there is no alias, then the column name will be used.
     * 
     * @param includeQuotes
     *            indicates whether or not the output should include quotes, if
     *            the select item's column has quotes associated (typically
     *            true, but false if used for presentation)
     */
    public String getSuperQueryAlias(boolean includeQuotes) {
        if (_alias != null) {
            return _alias;
        } else if (_column != null) {
            final StringBuilder sb = new StringBuilder();
            if (_function != null) {
                if (_functionApproximationAllowed) {
                    sb.append(FUNCTION_APPROXIMATION_PREFIX);
                }
                sb.append(_function.getFunctionName());
                sb.append('(');
            }
            if (includeQuotes) {
                sb.append(_column.getQuotedName());
            } else {
                sb.append(_column.getName());
            }
            if (_function != null) {
                sb.append(')');
            }
            return sb.toString();
        } else {
            logger.debug("Could not resolve a reasonable super-query alias for SelectItem: {}", toSql());
            return toStringNoAlias().toString();
        }
    }

    public String getSameQueryAlias() {
        return getSameQueryAlias(false);
    }

    /**
     * @return an alias that can be used in WHERE, GROUP BY and ORDER BY clauses
     *         in the same query
     */
    public String getSameQueryAlias(boolean includeSchemaInColumnPath) {
        if (_column != null) {
            StringBuilder sb = new StringBuilder();
            String columnPrefix = getToStringColumnPrefix(includeSchemaInColumnPath);
            sb.append(columnPrefix);
            sb.append(_column.getQuotedName());
            if (_function != null) {
                if (_functionApproximationAllowed) {
                    sb.insert(0, FUNCTION_APPROXIMATION_PREFIX + _function.getFunctionName() + "(");
                } else {
                    sb.insert(0, _function.getFunctionName() + "(");
                }
                sb.append(")");
            }
            return sb.toString();
        }
        String alias = getAlias();
        if (alias == null) {
            alias = toStringNoAlias(includeSchemaInColumnPath).toString();
            logger.debug("Could not resolve a reasonable same-query alias for SelectItem: {}", toSql());
        }
        return alias;
    }

    @Override
    public String toSql() {
        return toSql(false);
    }

    @Override
    public String toSql(boolean includeSchemaInColumnPath) {
        StringBuilder sb = toStringNoAlias(includeSchemaInColumnPath);
        if (_alias != null) {
            sb.append(" AS ");
            sb.append(_alias);
        }
        return sb.toString();
    }

    public StringBuilder toStringNoAlias() {
        return toStringNoAlias(false);
    }

    public StringBuilder toStringNoAlias(boolean includeSchemaInColumnPath) {
        StringBuilder sb = new StringBuilder();
        if (_column != null) {
            sb.append(getToStringColumnPrefix(includeSchemaInColumnPath));
            sb.append(_column.getQuotedName());
        }
        if (_expression != null) {
            sb.append(_expression);
        }
        if (_fromItem != null && _subQuerySelectItem != null) {
            if (_fromItem.getAlias() != null) {
                sb.append(_fromItem.getAlias() + '.');
            }
            sb.append(_subQuerySelectItem.getSuperQueryAlias());
        }
        if (_function != null) {
            if (_functionApproximationAllowed) {
                sb.insert(0, FUNCTION_APPROXIMATION_PREFIX + _function.getFunctionName() + "(");
            } else {
                sb.insert(0, _function.getFunctionName() + "(");
            }
            sb.append(")");
        }
        return sb;
    }

    private String getToStringColumnPrefix(boolean includeSchemaInColumnPath) {
        StringBuilder sb = new StringBuilder();
        if (_fromItem != null && _fromItem.getAlias() != null) {
            sb.append(_fromItem.getAlias());
            sb.append('.');
        } else {
            final Table table = _column.getTable();
            String tableLabel;
            if (_query == null) {
                tableLabel = null;
            } else {
                tableLabel = _query.getFromClause().getAlias(table);
            }
            if (table != null) {
                if (tableLabel == null) {
                    tableLabel = table.getQuotedName();
                    if (includeSchemaInColumnPath) {
                        Schema schema = table.getSchema();
                        if (schema != null) {
                            tableLabel = schema.getQuotedName() + "." + tableLabel;
                        }
                    }
                }
                sb.append(tableLabel);
                sb.append('.');
            }
        }
        return sb.toString();
    }

    public boolean equalsIgnoreAlias(SelectItem that) {
        return equalsIgnoreAlias(that, false);
    }

    public boolean equalsIgnoreAlias(SelectItem that, boolean exactColumnCompare) {
        if (that == null) {
            return false;
        }
        if (that == this) {
            return true;
        }

        EqualsBuilder eb = new EqualsBuilder();
        if (exactColumnCompare) {
            eb.append(this._column == that._column);
            eb.append(this._fromItem, that._fromItem);
        } else {
            eb.append(this._column, that._column);
        }
        eb.append(this._function, that._function);
        eb.append(this._functionApproximationAllowed, that._functionApproximationAllowed);
        eb.append(this._expression, that._expression);
        if (_subQuerySelectItem != null) {
            eb.append(_subQuerySelectItem.equalsIgnoreAlias(that._subQuerySelectItem));
        } else {
            if (that._subQuerySelectItem != null) {
                eb.append(false);
            }
        }
        return eb.isEquals();
    }

    @Override
    protected void decorateIdentity(List<Object> identifiers) {
        identifiers.add(_expression);
        identifiers.add(_alias);
        identifiers.add(_column);
        identifiers.add(_function);
        identifiers.add(_functionApproximationAllowed);
        identifiers.add(_fromItem);
        identifiers.add(_subQuerySelectItem);
    }

    @Override
    protected SelectItem clone() {
        final SelectItem subQuerySelectItem = (_subQuerySelectItem == null ? null : _subQuerySelectItem.clone());
        final FromItem fromItem = (_fromItem == null ? null : _fromItem.clone());
        final SelectItem s = new SelectItem(_column, fromItem, _function, _expression, subQuerySelectItem, _alias,
                _functionApproximationAllowed);
        return s;
    }

    /**
     * Creates a copy of the {@link SelectItem}, with a different
     * {@link FunctionType}.
     * 
     * @param function
     * @return
     */
    public SelectItem replaceFunction(FunctionType function) {
        return new SelectItem(_column, _fromItem, function, _expression, _subQuerySelectItem, _alias,
                _functionApproximationAllowed);
    }

    /**
     * Creates a copy of the {@link SelectItem}, with a different
     * {@link #isFunctionApproximationAllowed()} flag set.
     * 
     * @param functionApproximationAllowed
     * @return
     */
    public SelectItem replaceFunctionApproximationAllowed(boolean functionApproximationAllowed) {
        return new SelectItem(_column, _fromItem, _function, _expression, _subQuerySelectItem, _alias,
                functionApproximationAllowed);
    }

    /**
     * Investigates whether or not this SelectItem references a particular
     * column. This will search for direct references and indirect references
     * via subqueries.
     * 
     * @param column
     * @return a boolean that is true if the specified column is referenced by
     *         this SelectItem and false otherwise.
     */
    public boolean isReferenced(Column column) {
        if (column != null) {
            if (column.equals(_column)) {
                return true;
            }
            if (_subQuerySelectItem != null) {
                return _subQuerySelectItem.isReferenced(column);
            }
        }
        return false;
    }

    @Override
    public String toString() {
        return toSql();
    }
}