/*
 * 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.drill.exec.store.parquet.columnreaders.batchsizing;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.drill.common.map.CaseInsensitiveMap;
import org.apache.drill.common.types.TypeProtos.MajorType;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.exception.OutOfMemoryException;
import org.apache.drill.exec.record.MaterializedField;
import org.apache.drill.exec.server.options.OptionManager;
import org.apache.drill.exec.store.parquet.columnreaders.ParquetColumnMetadata;
import org.apache.drill.exec.store.parquet.columnreaders.ParquetSchema;
import org.apache.drill.exec.store.parquet.columnreaders.VarLenColumnBulkInput;
import org.apache.drill.exec.store.parquet.columnreaders.batchsizing.RecordBatchOverflow.FieldOverflowDefinition;
import org.apache.drill.exec.util.record.RecordBatchStats;
import org.apache.drill.exec.util.record.RecordBatchStats.RecordBatchStatsContext;
import org.apache.drill.exec.vector.AllocationHelper;
import org.apache.drill.exec.vector.ValueVector;
import com.google.common.base.Preconditions;

/**
 * This class is tasked with managing all aspects of flat Parquet reader record batch sizing logic.
 * Currently a record batch size is constrained with two parameters: Number of rows and Memory usage.
 */
public final class RecordBatchSizerManager {
  private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(RecordBatchSizerManager.class);


  /** Minimum column memory size */
  private static final int MIN_COLUMN_MEMORY_SZ = VarLenColumnBulkInput.getMinVLColumnMemorySize();

  /** Parquet schema object */
  private final ParquetSchema schema;
  /** Total records to read */
  private final long totalRecordsToRead;
  /** Logic to minimize overflow occurrences */
  private final BatchOverflowOptimizer overflowOptimizer;

  /** Configured Parquet records per batch */
  private final int configRecordsPerBatch;
  /** Configured Parquet memory size per batch */
  private final long configMemorySizePerBatch;
  /** An upper bound on the Parquet records per batch based on the configured value and schema */
  private int maxRecordsPerBatch;
  /** An upper bound on the Parquet memory size per batch based on the configured value and schema  */
  private long maxMemorySizePerBatch;
  /** The current number of records per batch as it can be dynamically optimized */
  private int recordsPerBatch;

  /** List of fixed columns */
  private final List<ColumnMemoryInfo> fixedLengthColumns = new ArrayList<ColumnMemoryInfo>();
  /** List of variable columns */
  private final List<ColumnMemoryInfo> variableLengthColumns = new ArrayList<ColumnMemoryInfo>();
  /** Field to column memory information map */
  private final Map<String, ColumnMemoryInfo> columnMemoryInfoMap = CaseInsensitiveMap.newHashMap();
  /** Indicator invoked when column(s) precision change */
  private boolean columnPrecisionChanged;

  /**
   * Field overflow map; this information is stored within this class for two reasons:
   * a) centralization to simplify resource deallocation (overflow data is backed by Direct Memory)
   * b) overflow is a result of batch constraints enforcement which this class manages the overflow logic
   */
  private Map<String, FieldOverflowStateContainer> fieldOverflowMap = CaseInsensitiveMap.newHashMap();

  /** For controlling batch statistics logging */
  private final RecordBatchStatsContext batchStatsContext;

  /**
   * Constructor.
   *
   * @param options drill options
   * @param schema current reader schema
   * @param totalRecordsToRead total number of rows to read
   */
  public RecordBatchSizerManager(OptionManager options,
    ParquetSchema schema,
    long totalRecordsToRead,
    RecordBatchStatsContext batchStatsContext) {

    this.schema = schema;
    this.totalRecordsToRead = totalRecordsToRead;
    this.configRecordsPerBatch = (int) options.getLong(ExecConstants.PARQUET_FLAT_BATCH_NUM_RECORDS);
    this.configMemorySizePerBatch = getConfiguredMaxBatchMemory(options);
    this.maxMemorySizePerBatch = this.configMemorySizePerBatch;
    this.maxRecordsPerBatch = this.configRecordsPerBatch;
    this.recordsPerBatch = this.configRecordsPerBatch;
    this.overflowOptimizer = new BatchOverflowOptimizer(columnMemoryInfoMap);
    this.batchStatsContext = batchStatsContext;
  }

  /**
   * Tunes record batch parameters based on configuration and schema.
   */
  public void setup() {

    // Normalize batch parameters
    this.maxMemorySizePerBatch = normalizeMemorySizePerBatch();
    this.maxRecordsPerBatch = normalizeNumRecordsPerBatch();

    // Let's load the column metadata
    loadColumnsPrecisionInfo();

    if (getNumColumns() == 0) {
      return; // there are cases where downstream operators don't select any columns
              // in such a case, Parquet will return the pseudo column _DEFAULT_COL_TO_READ_
    }

    // We need to divide the overall memory pool amongst all columns
    assignColumnsBatchMemory();

    // Initialize the overflow optimizer
    overflowOptimizer.setup();
  }

  /**
   * @return the schema
   */
  public ParquetSchema getSchema() {
    return schema;
  }

  /**
   * @return batch statistics context
   */
  public RecordBatchStatsContext getBatchStatsContext() {
    return batchStatsContext;
  }

  /**
   * Allocates value vectors for the current batch.
   *
   * @param vectorMap a collection of value vectors keyed by their field names
   * @throws OutOfMemoryException
   */
  public void allocate(Map<String, ValueVector> vectorMap) throws OutOfMemoryException {

    if (columnPrecisionChanged) {
      // We need to divide the overall memory pool amongst all columns
      assignColumnsBatchMemory();
    }

    try {
      for (final ValueVector v : vectorMap.values()) {
        ColumnMemoryInfo columnMemoryInfo = columnMemoryInfoMap.get(v.getField().getName());

        if (columnMemoryInfo != null) {
          Preconditions.checkState(columnMemoryInfo.columnPrecision <= Integer.MAX_VALUE, "Column precision cannot exceed 2GB");
          AllocationHelper.allocate(v, recordsPerBatch, (int) columnMemoryInfo.columnPrecision, 0);
        } else {
          // This column was found in another Parquet file but not the current one; so we inject
          // a null value. At this time, we do not account for such columns. Why? the right design is
          // to create a ZERO byte all-nulls value vector to handle such columns (there could be hundred of these).
          AllocationHelper.allocate(v, recordsPerBatch, 0, 0); // the helper will still use a precision of 1
        }
      }
    } catch (NullPointerException e) {
      throw new OutOfMemoryException();
    }
  }

  /**
   * @return the field overflow state map
   */
  public Map<String, FieldOverflowStateContainer> getFieldOverflowMap() {
    return fieldOverflowMap;
  }

  /**
   * @param field materialized field
   * @return field overflow state container
   */
  public FieldOverflowStateContainer getFieldOverflowContainer(String field) {
    return fieldOverflowMap.get(field);
  }

  /**
   * Releases the overflow data resources associated with this field; also removes the overflow
   * container from the overflow containers map.
   *
   * @param field materialized field
   * @return true if this field's overflow container was removed from the overflow containers map
   */
  public boolean releaseFieldOverflowContainer(String field) {
    return releaseFieldOverflowContainer(field, true);
  }

  /**
   * @param field materialized field
   * @return field batch memory quota
   */
  public ColumnMemoryQuota getCurrentFieldBatchMemory(String field) {
    return columnMemoryInfoMap.get(field).columnMemoryQuota;
  }

  /**
   * @return current number of records per batch (may change across batches)
   */
  public int getCurrentRecordsPerBatch() {
    return recordsPerBatch;
  }

  /**
   * @return current total memory per batch (may change across batches)
   */
  public long getCurrentMemorySizePerBatch() {
    return maxMemorySizePerBatch; // Current logic doesn't mutate the max-memory after it has been set
  }

  /**
   * @return configured number of records per batch (may be different from the enforced one)
   */
  public int getConfigRecordsPerBatch() {
    return configRecordsPerBatch;
  }

  /**
   * @return configured memory size per batch (may be different from the enforced one)
   */
  public long getConfigMemorySizePerBatch() {
    return configMemorySizePerBatch;
  }

  /**
   * Enables this object to optimize the impact of overflows by computing more
   * accurate VL column precision.
   *
   * @param batchNumRecords number of records in this batch
   * @param batchStats columns statistics
   */
  public void onEndOfBatch(int batchNumRecords, List<VarLenColumnBatchStats> batchStats) {
    columnPrecisionChanged = overflowOptimizer.onEndOfBatch(batchNumRecords, batchStats);
  }

  /**
   * Closes all resources managed by this object
   */
  public void close() {

    for (String field: fieldOverflowMap.keySet()) {
      releaseFieldOverflowContainer(field, false);
    }

    // now clear the map
    fieldOverflowMap.clear();
  }

// ----------------------------------------------------------------------------
// Internal implementation logic
// ----------------------------------------------------------------------------

  private long getConfiguredMaxBatchMemory(OptionManager options) {
    // Use the parquet specific configuration if set
    long maxMemory = options.getLong(ExecConstants.PARQUET_FLAT_BATCH_MEMORY_SIZE);

    // Otherwise, use the common property
    if (maxMemory <= 0) {
      maxMemory = options.getLong(ExecConstants.OUTPUT_BATCH_SIZE);
    }
    return maxMemory;
  }

  private int normalizeNumRecordsPerBatch() {
    int normalizedNumRecords = configRecordsPerBatch;

    if (configRecordsPerBatch <= 0) {
      final String message = String.format("Invalid Parquet number of record(s) per batch [%d]",
        configRecordsPerBatch);

      throw new IllegalArgumentException(message);
    }

    if (normalizedNumRecords > totalRecordsToRead) {
      if (logger.isDebugEnabled()) {
        final String message = String.format("The requested number of record(s) to read is lower than the records per batch; "
          + "updating the number of record(s) per batch from [%d] to [%d]",
          normalizedNumRecords, totalRecordsToRead);
        logger.debug(message);
      }
      normalizedNumRecords = (int) totalRecordsToRead;
    }

    if (batchStatsContext.isEnableBatchSzLogging()) {
      final String message = String.format("The Parquet reader number of record(s) has been set to [%d]", normalizedNumRecords);
      RecordBatchStats.logRecordBatchStats(message, batchStatsContext);
    }

    return normalizedNumRecords;
  }

  private long normalizeMemorySizePerBatch() {
    long normalizedMemorySize = configMemorySizePerBatch;

    if (normalizedMemorySize <= 0) {
      final String message = String.format("Invalid Parquet memory per batch [%d] byte(s)",
        configMemorySizePerBatch);

      throw new IllegalArgumentException(message);
    }

    // Ensure the minimal memory size per column is satisfied
    final int numColumns = schema.getColumnMetadata().size();

    if (numColumns == 0) {
      return normalizedMemorySize; // NOOP
    }

    final long memorySizePerColumn = normalizedMemorySize / numColumns;

    if (memorySizePerColumn < MIN_COLUMN_MEMORY_SZ) {
      final long prevValue   = normalizedMemorySize;
      normalizedMemorySize  = MIN_COLUMN_MEMORY_SZ * numColumns;

      final String message = String.format("The Parquet memory per batch [%d] byte(s) is too low for this query ; using [%d] bytes",
        prevValue, normalizedMemorySize);
      logger.warn(message);
    }

    if (batchStatsContext.isEnableBatchSzLogging()) {
      RecordBatchStats.printConfiguredBatchSize(batchStatsContext, (int) normalizedMemorySize);
    }

    return normalizedMemorySize;
  }

  private void loadColumnsPrecisionInfo() {
    assert fixedLengthColumns.size() == 0;
    assert variableLengthColumns.size() == 0;

    for (ParquetColumnMetadata columnMetadata : schema.getColumnMetadata()) {
      assert !columnMetadata.isRepeated() : "This reader doesn't handle repeated columns..";

      ColumnMemoryInfo columnMemoryInfo = new ColumnMemoryInfo();
      columnMemoryInfoMap.put(columnMetadata.getField().getName(), columnMemoryInfo);

      if (columnMetadata.isFixedLength()) {
        columnMemoryInfo.columnMeta = columnMetadata;
        columnMemoryInfo.columnPrecision = BatchSizingMemoryUtil.getFixedColumnTypePrecision(columnMetadata);
        columnMemoryInfo.columnMemoryQuota.reset();

        fixedLengthColumns.add(columnMemoryInfo);
      } else {

        columnMemoryInfo.columnMeta = columnMetadata;
        columnMemoryInfo.columnPrecision = BatchSizingMemoryUtil.getAvgVariableLengthColumnTypePrecision(columnMetadata);
        columnMemoryInfo.columnMemoryQuota.reset();

        variableLengthColumns.add(columnMemoryInfo);
      }
    }
  }

  private void assignColumnsBatchMemory() {

    if (getNumColumns() == 0 ||
        maxRecordsPerBatch == 0) { // Happens when all row-groups are pruned, and only one is returned empty (TODO: currently not empty)
      return;
    }

    recordsPerBatch = maxRecordsPerBatch;

    // Cache the original records per batch as it may change
    int originalRecordsPerBatch = recordsPerBatch;

    // Perform the fine-grained memory quota assignment
    assignFineGrainedMemoryQuota();

    // log the new record batch if it changed
    if (batchStatsContext.isEnableBatchSzLogging()) {
      assert recordsPerBatch <= maxRecordsPerBatch;

      if (originalRecordsPerBatch != recordsPerBatch) {
        final String message = String.format("The Parquet records per batch [%d] has been decreased to [%d]", originalRecordsPerBatch, recordsPerBatch);
        RecordBatchStats.logRecordBatchStats(message, batchStatsContext);
      }

      // Now dump the per column memory quotas
      dumpColumnMemoryQuotas();
    }
  }

  private void assignFineGrainedMemoryQuota() {

    // - Compute the memory required based on the current batch size and assigned column precision
    // - Compute the ration have-memory / needed-memory
    // - if less than one, new-num-records = num-recs * ratio; go back to previous steps
    // - distribute the extra memory uniformly across the variable length columns

    MemoryRequirementContainer requiredMemory = new MemoryRequirementContainer();
    int newRecordsPerBatch = recordsPerBatch;

    while (true) {
      // Compute max-memory / needed-memory-for-current-num-records
      recordsPerBatch          = newRecordsPerBatch;
      double neededMemoryRatio = computeNeededMemoryRatio(requiredMemory);
      assert neededMemoryRatio <= 1;

      newRecordsPerBatch = (int) (recordsPerBatch * neededMemoryRatio);
      assert newRecordsPerBatch <= recordsPerBatch;

      if (newRecordsPerBatch <= 1) {
        recordsPerBatch = 1;
        computeNeededMemoryRatio(requiredMemory); // update the memory quota with this new number of records
        break; // we cannot process less than one row

      } else if (newRecordsPerBatch < recordsPerBatch) {
        // We computed a new number of records per batch; we need to
        // a) make sure this new number satisfies our needs and b)
        // per per column quota
        continue;
      }
      assert recordsPerBatch == newRecordsPerBatch;

      // Alright, we have now found the target number of records; we need
      // only to adjust the remaining memory (if any) amongst the variable
      // length columns.
      distributeExtraMemorySpace(requiredMemory);
      break; // we're done
    }
  }

  private void distributeExtraMemorySpace(MemoryRequirementContainer requiredMemory) {
    // Distribute uniformly the extra memory space to the variable length columns
    // to minimize the chance of overflow conditions.
    final int numVariableLengthColumns = variableLengthColumns.size();

    if (numVariableLengthColumns == 0) {
      return; // we're done
    }

    final long totalMemoryNeeded = requiredMemory.fixedLenRequiredMemory + requiredMemory.variableLenRequiredMemory;
    final long extraMemorySpace = maxMemorySizePerBatch - totalMemoryNeeded;
    final long perColumnExtraSpace = extraMemorySpace / numVariableLengthColumns;

    if (perColumnExtraSpace == 0) {
      return;
    }

    for (ColumnMemoryInfo columnInfo : variableLengthColumns) {
      columnInfo.columnMemoryQuota.maxMemoryUsage += perColumnExtraSpace;
    }
  }

  private int getNumColumns() {
    return fixedLengthColumns.size() + variableLengthColumns.size();
  }

  private boolean releaseFieldOverflowContainer(String field, boolean remove) {
    FieldOverflowStateContainer container = getFieldOverflowContainer(field);

    if (container == null) {
      return false; // NOOP
    }

    // We need to release resources associated with this container
    container.release();
    container.overflowDef = null;
    container.overflowState = null;

    if (remove) {
      // Finally remove this container from the map
      fieldOverflowMap.remove(field);
    }

    return remove;
  }

  private long computeVectorMemory(ColumnMemoryInfo columnInfo, int numValues) {
    if (columnInfo.columnMeta.isFixedLength()) {
      return BatchSizingMemoryUtil.computeFixedLengthVectorMemory(columnInfo.columnMeta, numValues);
    }
    return BatchSizingMemoryUtil.computeVariableLengthVectorMemory(
      columnInfo.columnMeta,
      columnInfo.columnPrecision,
      numValues);
  }

  private double computeNeededMemoryRatio(MemoryRequirementContainer requiredMemory) {
    requiredMemory.reset();

    for (ColumnMemoryInfo columnInfo : fixedLengthColumns) {
      columnInfo.columnMemoryQuota.maxMemoryUsage = computeVectorMemory(columnInfo, recordsPerBatch);
      columnInfo.columnMemoryQuota.maxNumValues   = recordsPerBatch;
      requiredMemory.fixedLenRequiredMemory      += columnInfo.columnMemoryQuota.maxMemoryUsage;
    }

    for (ColumnMemoryInfo columnInfo : variableLengthColumns) {
      columnInfo.columnMemoryQuota.maxMemoryUsage = computeVectorMemory(columnInfo, recordsPerBatch);
      columnInfo.columnMemoryQuota.maxNumValues   = recordsPerBatch;
      requiredMemory.variableLenRequiredMemory   += columnInfo.columnMemoryQuota.maxMemoryUsage;
    }

    final long totalMemoryNeeded = requiredMemory.fixedLenRequiredMemory + requiredMemory.variableLenRequiredMemory;
    assert totalMemoryNeeded > 0;

    double neededMemoryRatio = ((double) maxMemorySizePerBatch) / totalMemoryNeeded;

    return neededMemoryRatio > 1 ? 1 : neededMemoryRatio;
  }

  private void dumpColumnMemoryQuotas() {
    StringBuilder msg = new StringBuilder();
    msg.append(": Field Quotas:\n\tName\tType\tPrec\tQuota\n");

    for (ColumnMemoryInfo columnInfo : columnMemoryInfoMap.values()) {
      msg.append("\t");
      msg.append(RecordBatchStats.BATCH_STATS_PREFIX);
      msg.append("\t");
      msg.append(columnInfo.columnMeta.getField().getName());
      msg.append("\t");
      printType(columnInfo.columnMeta.getField(), msg);
      msg.append("\t");
      msg.append(columnInfo.columnPrecision);
      msg.append("\t");
      msg.append(columnInfo.columnMemoryQuota.maxMemoryUsage);
      msg.append("\n");
    }

    RecordBatchStats.logRecordBatchStats(msg.toString(), batchStatsContext);
  }

  private  static void printType(MaterializedField field, StringBuilder msg) {
    final MajorType type = field.getType();

    msg.append(type.getMinorType().name());
    msg.append(':');
    msg.append(type.getMode().name());
  }


// ----------------------------------------------------------------------------
// Inner Data Structure
// ----------------------------------------------------------------------------

  /** An abstraction to allow column readers attach custom field overflow state */
  public static interface FieldOverflowState {

    /** Overflow data can become an input source for the next batch(s); this method
     * allows the reader framework to inform individual readers on the number of
     * values that have been consumed from the current overflow data
     *
     * @param numValues the number of values consumed within the current batch
     */
    void onNewBatchValuesConsumed(int numValues);

    /**
     * @return true if the overflow data has been fully consumed (all overflow data consumed by
     *              the Parquet reader)
     */
    boolean isOverflowDataFullyConsumed();
  }

  /** Container object to hold current field overflow state */
  public static final class FieldOverflowStateContainer {
    /** Field overflow definition */
    public FieldOverflowDefinition overflowDef;
    /** Field overflow state */
    public FieldOverflowState overflowState;

    public FieldOverflowStateContainer(FieldOverflowDefinition overflowDef, FieldOverflowState overflowState) {
      this.overflowDef   = overflowDef;
      this.overflowState = overflowState;
    }

    private void release() {
      if (overflowDef != null) {
        if (logger.isDebugEnabled()) {
          logger.debug(String.format(
            "Releasing a buffer of length %d used to handle overflow data", overflowDef.buffer.capacity()));
        }
        overflowDef.buffer.release();
      }
      overflowDef = null;
      overflowState = null;
    }
  }

  /** Container object to supply variable columns statistics to the batch sizer */
  public final static class VarLenColumnBatchStats {
    /** Value vector associated with a VL column */
    public final ValueVector vector;
    /** Number of values read in the current batch */
    public final int numValuesRead;

    /**
     * Constructor.
     * @param vector value vector
     * @param numValuesRead number of values
     */
    public VarLenColumnBatchStats(ValueVector vector, int numValuesRead) {
      this.vector = vector;
      this.numValuesRead = numValuesRead;
    }
  }

  /** Field memory quota */
  public static final class ColumnMemoryQuota {
    /** Maximum cumulative memory that could be used */
    private long maxMemoryUsage;
    /** Maximum number of values that could be inserted */
    private int maxNumValues;

    public ColumnMemoryQuota() {
    }

    /**
     * @param maxMemoryUsage maximum cumulative memory that could be used
     */
    public ColumnMemoryQuota(long maxMemoryUsage) {
      this.maxMemoryUsage = maxMemoryUsage;
    }

    /**
     * @return the maxMemoryUsage
     */
    public long getMaxMemoryUsage() {
      return maxMemoryUsage;
    }

    /**
     * @return the maxNumValues
     */
    public int getMaxNumValues() {
      return maxNumValues;
    }

    void reset() {
      maxMemoryUsage = 0;
      maxNumValues = 0;
    }
  }

  /** A container which holds a column memory precision & current quota information */
  static final class ColumnMemoryInfo {
    /** Column metadata */
    ParquetColumnMetadata columnMeta;
    /** Column value precision (maximum length for VL columns) */
    long columnPrecision;
    /** Column current memory quota within a batch */
    final ColumnMemoryQuota columnMemoryQuota = new ColumnMemoryQuota();
  }

  /** Memory requirements container */
  static final class MemoryRequirementContainer {
    /** Memory needed for the fixed length columns given a specific record size */
    private long fixedLenRequiredMemory;
    /** Memory needed for the fixed length columns given a specific record size */
    private long variableLenRequiredMemory;

    private void reset() {
      this.fixedLenRequiredMemory    = 0;
      this.variableLenRequiredMemory = 0;
    }
  }

}
