/*
 * 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.io.IOException;
import java.sql.SQLException;
import java.util.List;

import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
import org.apache.phoenix.execute.MutationState;
import org.apache.phoenix.hbase.index.covered.update.ColumnReference;
import org.apache.phoenix.index.IndexMaintainer;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixStatement;
import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
import org.apache.phoenix.schema.PTable;
import org.apache.phoenix.schema.SortOrder;
import org.apache.phoenix.schema.TableRef;
import org.apache.phoenix.schema.types.PLong;
import org.apache.phoenix.util.ByteUtil;
import org.apache.phoenix.util.ScanUtil;

import com.google.common.collect.Lists;

/**
 * For local indexes, we optimize the initial index population by *not* sending
 * Puts over the wire for the index rows, as we don't need to do that. Instead,
 * we tap into our region observer to generate the index rows based on the data
 * rows as we scan
 */
public class PostLocalIndexDDLCompiler {
	private final PhoenixConnection connection;
    private final String tableName;
    
    public PostLocalIndexDDLCompiler(PhoenixConnection connection, String tableName) {
        this.connection = connection;
        this.tableName = tableName;
    }

	public MutationPlan compile(final PTable index) throws SQLException {
		try (final PhoenixStatement statement = new PhoenixStatement(connection)) {
            String query = "SELECT count(*) FROM " + tableName;
            final QueryPlan plan = statement.compileQuery(query);
            TableRef tableRef = plan.getTableRef();
            Scan scan = plan.getContext().getScan();
            ImmutableBytesWritable ptr = new ImmutableBytesWritable();
            final PTable dataTable = tableRef.getTable();
            List<PTable> indexes = Lists.newArrayListWithExpectedSize(1);
            // Only build newly created index.
            indexes.add(index);
            IndexMaintainer.serialize(dataTable, ptr, indexes, plan.getContext().getConnection());
            // Set attribute on scan that UngroupedAggregateRegionObserver will switch on.
            // We'll detect that this attribute was set the server-side and write the index
            // rows per region as a result. The value of the attribute will be our persisted
            // index maintainers.
            // Define the LOCAL_INDEX_BUILD as a new static in BaseScannerRegionObserver
            scan.setAttribute(BaseScannerRegionObserver.LOCAL_INDEX_BUILD, ByteUtil.copyKeyBytesIfNecessary(ptr));
            // By default, we'd use a FirstKeyOnly filter as nothing else needs to be projected for count(*).
            // However, in this case, we need to project all of the data columns that contribute to the index.
            IndexMaintainer indexMaintainer = index.getIndexMaintainer(dataTable, connection);
            for (ColumnReference columnRef : indexMaintainer.getAllColumns()) {
                scan.addColumn(columnRef.getFamily(), columnRef.getQualifier());
            }

            // Go through MutationPlan abstraction so that we can create local indexes
            // with a connectionless connection (which makes testing easier).
            return new BaseMutationPlan(plan.getContext(), Operation.UPSERT) {

                @Override
                public MutationState execute() throws SQLException {
                    connection.getMutationState().commitDDLFence(dataTable);
                    Cell kv = plan.iterator().next().getValue(0);
                    ImmutableBytesWritable tmpPtr = new ImmutableBytesWritable(kv.getValueArray(), kv.getValueOffset(), kv.getValueLength());
                    // A single Cell will be returned with the count(*) - we decode that here
                    long rowCount = PLong.INSTANCE.getCodec().decodeLong(tmpPtr, SortOrder.getDefault());
                    // The contract is to return a MutationState that contains the number of rows modified. In this
                    // case, it's the number of rows in the data table which corresponds to the number of index
                    // rows that were added.
                    return new MutationState(0, connection, rowCount);
                }

            };
        }
	}
	
}
