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

import java.sql.SQLException;
import java.text.Format;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;

import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.util.Pair;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixStatement;
import org.apache.phoenix.monitoring.OverAllQueryMetrics;
import org.apache.phoenix.monitoring.ReadMetricQueue;
import org.apache.phoenix.parse.SelectStatement;
import org.apache.phoenix.query.QueryConstants;
import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.schema.MetaDataClient;
import org.apache.phoenix.schema.PColumn;
import org.apache.phoenix.schema.PTable;
import org.apache.phoenix.schema.PTableType;
import org.apache.phoenix.schema.TableRef;
import org.apache.phoenix.util.DateUtil;
import org.apache.phoenix.util.NumberUtil;
import org.apache.phoenix.util.ReadOnlyProps;

import com.google.common.collect.Maps;


/**
 *
 * Class that keeps common state used across processing the various clauses in a
 * top level JDBC statement such as SELECT, UPSERT, DELETE, etc.
 *
 *
 * @since 0.1
 */
public class StatementContext {
    private ColumnResolver resolver;
    private final BindManager binds;
    private final Scan scan;
    private final ExpressionManager expressions;
    private final AggregationManager aggregates;
    private final String dateFormat;
    private final Format dateFormatter;
    private final String timeFormat;
    private final Format timeFormatter;
    private final String timestampFormat;
    private final Format timestampFormatter;
    private final TimeZone dateFormatTimeZone;
    private final String numberFormat;
    private final ImmutableBytesWritable tempPtr;
    private final PhoenixStatement statement;
    private final Map<PColumn, Integer> dataColumns;

    private long currentTime = QueryConstants.UNSET_TIMESTAMP;
    private ScanRanges scanRanges = ScanRanges.EVERYTHING;
    private final SequenceManager sequences;

    private TableRef currentTable;
    private List<Pair<byte[], byte[]>> whereConditionColumns;
    private Map<SelectStatement, Object> subqueryResults;
    private final ReadMetricQueue readMetricsQueue;
    private final OverAllQueryMetrics overAllQueryMetrics;
    
    public StatementContext(PhoenixStatement statement) {
        this(statement, new Scan());
    }
    
    /**
     *  Constructor that lets you override whether or not to collect request level metrics.
     */
    public StatementContext(PhoenixStatement statement, boolean collectRequestLevelMetrics) {
        this(statement, FromCompiler.EMPTY_TABLE_RESOLVER, new Scan(), new SequenceManager(statement), collectRequestLevelMetrics);
    }

    public StatementContext(PhoenixStatement statement, Scan scan) {
        this(statement, FromCompiler.EMPTY_TABLE_RESOLVER, new Scan(), new SequenceManager(statement));
    }

    public StatementContext(PhoenixStatement statement, ColumnResolver resolver) {
        this (statement, resolver, new Scan(), new SequenceManager(statement));
    }

    public StatementContext(PhoenixStatement statement, ColumnResolver resolver, Scan scan, SequenceManager seqManager) {
        this(statement, resolver, scan, seqManager, statement.getConnection().isRequestLevelMetricsEnabled());
    }
    
    public StatementContext(PhoenixStatement statement, ColumnResolver resolver, Scan scan, SequenceManager seqManager, boolean isRequestMetricsEnabled) {
        this.statement = statement;
        this.resolver = resolver;
        this.scan = scan;
        this.sequences = seqManager;
        this.binds = new BindManager(statement.getParameters());
        this.aggregates = new AggregationManager();
        this.expressions = new ExpressionManager();
        PhoenixConnection connection = statement.getConnection();
        ReadOnlyProps props = connection.getQueryServices().getProps();
        this.dateFormat = props.get(QueryServices.DATE_FORMAT_ATTRIB, DateUtil.DEFAULT_DATE_FORMAT);
        this.dateFormatter = DateUtil.getDateFormatter(dateFormat);
        this.timeFormat = props.get(QueryServices.TIME_FORMAT_ATTRIB, DateUtil.DEFAULT_TIME_FORMAT);
        this.timeFormatter = DateUtil.getTimeFormatter(timeFormat);
        this.timestampFormat = props.get(QueryServices.TIMESTAMP_FORMAT_ATTRIB, DateUtil.DEFAULT_TIMESTAMP_FORMAT);
        this.timestampFormatter = DateUtil.getTimestampFormatter(timestampFormat);
        this.dateFormatTimeZone = DateUtil.getTimeZone(props.get(QueryServices.DATE_FORMAT_TIMEZONE_ATTRIB,
                DateUtil.DEFAULT_TIME_ZONE_ID));
        this.numberFormat = props.get(QueryServices.NUMBER_FORMAT_ATTRIB, NumberUtil.DEFAULT_NUMBER_FORMAT);
        this.tempPtr = new ImmutableBytesWritable();
        this.currentTable = resolver != null && !resolver.getTables().isEmpty() ? resolver.getTables().get(0) : null;
        this.whereConditionColumns = new ArrayList<Pair<byte[], byte[]>>();
        this.dataColumns = this.currentTable == null ? Collections.<PColumn, Integer> emptyMap() : Maps
                .<PColumn, Integer> newLinkedHashMap();
        this.subqueryResults = Maps.<SelectStatement, Object> newHashMap();
        this.readMetricsQueue = new ReadMetricQueue(isRequestMetricsEnabled);
        this.overAllQueryMetrics = new OverAllQueryMetrics(isRequestMetricsEnabled);
    }

    /**
     * build map from dataColumn to what will be its position in single KeyValue value bytes
     * returned from the coprocessor that joins from the index row back to the data row.
     * @param column
     * @return
     */
    public int getDataColumnPosition(PColumn column) {
        Integer pos = dataColumns.get(column);
        if (pos == null) {
            pos = dataColumns.size();
            dataColumns.put(column, pos);
        }
        return pos;
    }

    /**
     * @return return set of data columns.
     */
    public Set<PColumn> getDataColumns() {
        return dataColumns.keySet();
    }

    /**
     * @return map of data columns and their positions.
     */
    public Map<PColumn, Integer> getDataColumnsMap() {
        return dataColumns;
    }

    public String getDateFormat() {
        return dateFormat;
    }

    public TimeZone getDateFormatTimeZone() {
        return dateFormatTimeZone;
    }

    public Format getDateFormatter() {
        return dateFormatter;
    }

    public String getTimeFormat() {
        return timeFormat;
    }

    public Format getTimeFormatter() {
        return timeFormatter;
    }

    public String getTimestampFormat() {
        return timestampFormat;
    }

    public Format getTimestampFormatter() {
        return timestampFormatter;
    }

    public String getNumberFormat() {
        return numberFormat;
    }

    public Scan getScan() {
        return scan;
    }

    public BindManager getBindManager() {
        return binds;
    }

    public TableRef getCurrentTable() {
        return currentTable;
    }

    public void setCurrentTable(TableRef table) {
        this.currentTable = table;
    }

    public AggregationManager getAggregationManager() {
        return aggregates;
    }

    public ColumnResolver getResolver() {
        return resolver;
    }

    public void setResolver(ColumnResolver resolver) {
        this.resolver = resolver;
    }

    public ExpressionManager getExpressionManager() {
        return expressions;
    }


    public ImmutableBytesWritable getTempPtr() {
        return tempPtr;
    }

    public ScanRanges getScanRanges() {
        return this.scanRanges;
    }

    public void setScanRanges(ScanRanges scanRanges) {
        this.scanRanges = scanRanges;
        scanRanges.initializeScan(scan);
    }

    public PhoenixConnection getConnection() {
        return statement.getConnection();
    }

    public PhoenixStatement getStatement() {
        return statement;
    }

    public long getCurrentTime() throws SQLException {
        long ts = this.getCurrentTable().getTimeStamp();
        // if the table is transactional then it is only resolved once per query, so we can't use the table timestamp
        if (this.getCurrentTable().getTable().getType() != PTableType.PROJECTED && !this
                .getCurrentTable().getTable().isTransactional() && ts != QueryConstants
                .UNSET_TIMESTAMP) {
            return ts;
        }
        if (currentTime != QueryConstants.UNSET_TIMESTAMP) {
            return currentTime;
        }
        /*
         * For an UPSERT VALUES where autocommit off, we won't hit the server until the commit.
         * However, if the statement has a CURRENT_DATE() call as a value, we need to know the
         * current time at execution time. In that case, we'll call MetaDataClient.updateCache
         * purely to bind the current time based on the server time.
         */
        PTable table = this.getCurrentTable().getTable();
        PhoenixConnection connection = getConnection();
        MetaDataClient client = new MetaDataClient(connection);
        currentTime = client.getCurrentTime(table.getSchemaName().getString(), table.getTableName().getString());
        return currentTime;
    }

    public SequenceManager getSequenceManager(){
        return sequences;
    }

    public void addWhereConditionColumn(byte[] cf, byte[] q) {
        whereConditionColumns.add(new Pair<byte[], byte[]>(cf, q));
    }

    public List<Pair<byte[], byte[]>> getWhereConditionColumns() {
        return whereConditionColumns;
    }

    public boolean isSubqueryResultAvailable(SelectStatement select) {
        return subqueryResults.containsKey(select);
    }

    public Object getSubqueryResult(SelectStatement select) {
        return subqueryResults.get(select);
    }

    public void setSubqueryResult(SelectStatement select, Object result) {
        subqueryResults.put(select, result);
    }
    
    public ReadMetricQueue getReadMetricsQueue() {
        return readMetricsQueue;
    }
    
    public OverAllQueryMetrics getOverallQueryMetrics() {
        return overAllQueryMetrics;
    }
    
}
