/*
 * 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.hbase.index.builder;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.client.Increment;
import org.apache.hadoop.hbase.client.Mutation;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress;
import org.apache.hadoop.hbase.util.Pair;
import org.apache.phoenix.coprocessor.BaseScannerRegionObserver.ReplayWrite;
import org.apache.phoenix.hbase.index.covered.IndexCodec;
import org.apache.phoenix.hbase.index.covered.IndexMetaData;
import org.apache.phoenix.hbase.index.covered.NonTxIndexBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Basic implementation of the {@link IndexBuilder} that doesn't do any actual work of indexing.
 * <p>
 * You should extend this class, rather than implementing IndexBuilder directly to maintain compatability going forward.
 * <p>
 * Generally, you should consider using one of the implemented IndexBuilders (e.g {@link NonTxIndexBuilder}) as there is
 * a lot of work required to keep an index table up-to-date.
 */
public abstract class BaseIndexBuilder implements IndexBuilder {
    public static final String CODEC_CLASS_NAME_KEY = "org.apache.hadoop.hbase.index.codec.class";
    private static final Logger LOGGER = LoggerFactory.getLogger(BaseIndexBuilder.class);

    protected boolean stopped;
    protected RegionCoprocessorEnvironment env;
    protected IndexCodec codec;

    @Override
    public void extendBaseIndexBuilderInstead() {}

    @Override
    public void setup(RegionCoprocessorEnvironment env) throws IOException {
        this.env = env;
        // setup the phoenix codec. Generally, this will just be in standard one, but abstracting here
        // so we can use it later when generalizing covered indexes
        Configuration conf = env.getConfiguration();
        Class<? extends IndexCodec> codecClass = conf.getClass(CODEC_CLASS_NAME_KEY, null, IndexCodec.class);
        try {
            Constructor<? extends IndexCodec> meth = codecClass.getDeclaredConstructor(new Class[0]);
            meth.setAccessible(true);
            this.codec = meth.newInstance();
            this.codec.initialize(conf, env.getRegion().getRegionInfo().getTable().getName());
        } catch (Exception e) {
            throw new IOException(e);
        }
    }

    @Override
    public void batchStarted(MiniBatchOperationInProgress<Mutation> miniBatchOp, IndexMetaData context) throws IOException {
        // noop
    }
    
    @Override
    public IndexMetaData getIndexMetaData(MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
        return IndexMetaData.NULL_INDEX_META_DATA;
    }

    @Override
    public void batchCompleted(MiniBatchOperationInProgress<Mutation> miniBatchOp) {
        // noop
    }

    /**
     * By default, we always attempt to index the mutation. Commonly this can be slow (because the framework spends the
     * time to do the indexing, only to realize that you don't need it) or not ideal (if you want to turn on/off
     * indexing on a table without completely reloading it).
     * 
     * @throws IOException
     */
    @Override
    public boolean isEnabled(Mutation m) {
        // ask the codec to see if we should even attempt indexing
        return this.codec.isEnabled(m);
    }

    @Override
    public boolean isAtomicOp(Mutation m) {
        return false;
    }

    @Override
    public List<Mutation> executeAtomicOp(Increment inc) throws IOException {
        return null;
    }
    
    /**
     * Exposed for testing!
     * 
     * @param codec
     *            codec to use for this instance of the builder
     */
    public void setIndexCodecForTesting(IndexCodec codec) {
        this.codec = codec;
    }

    @Override
    public Collection<Pair<Mutation, byte[]>> getIndexUpdateForFilteredRows(Collection<Cell> filtered, IndexMetaData context)
            throws IOException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void stop(String why) {
        LOGGER.debug("Stopping because: " + why);
        this.stopped = true;
    }

    @Override
    public boolean isStopped() {
        return this.stopped;
    }

    @Override
    public ReplayWrite getReplayWrite(Mutation m) {
        return null;
    }

    public RegionCoprocessorEnvironment getEnv() {
        return this.env;
    }
}