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

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.drill.exec.vector.AllocationHelper;
import org.apache.drill.exec.vector.ValueVector;
import org.apache.drill.exec.vector.complex.AbstractMapVector;
import org.apache.drill.exec.vector.complex.AbstractRepeatedMapVector;
import org.apache.drill.common.map.CaseInsensitiveMap;

import com.google.common.annotations.VisibleForTesting;

/**
 * Prototype mechanism to allocate vectors based on expected
 * data sizes. This version uses a name-based map of fields
 * to sizes. Better to represent the batch structurally and
 * simply iterate over the schema rather than doing a per-field
 * lookup. But, the mechanisms needed to do the efficient solution
 * don't exist yet.
 * <p>
 * The element count is a float because it might be fractional.
 * If every tenth array has an element, then the count per array
 * is 0.1.
 */

public class VectorInitializer {

  @VisibleForTesting
  public static class AllocationHint {
    public final int entryWidth;
    public final float elementCount;

    private AllocationHint(int width, float elements) {
      entryWidth = width;
      elementCount = elements;
    }

    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder()
        .append("{");
      String sep = "";
      if (entryWidth > 0) {
        buf.append("width=")
          .append(entryWidth);
        sep = ", ";
      }
      if (elementCount > 0) {
        buf.append(sep)
          .append("elements=")
          .append(elementCount);
      }
      buf.append("}");
      return buf.toString();
    }
  }

  private Map<String, AllocationHint> hints = CaseInsensitiveMap.newHashMap();

  public void variableWidth(String name, int width) {
    hints.put(name, new AllocationHint(width, 1));
  }

  public void fixedWidthArray(String name, float elements) {
    hints.put(name, new AllocationHint(0, elements));
  }

  public void variableWidthArray(String name, float width, float elements) {
    hints.put(name, new AllocationHint((int) Math.ceil(width), elements));
  }

  public AllocationHint hint(String name) {
    return hints.get(name);
  }

  public void allocateBatch(VectorAccessible va, int recordCount) {
    for (VectorWrapper<?> w: va) {
      allocateVector(w.getValueVector(), "", recordCount);
    }
  }

  public void allocateVectors(List<ValueVector> valueVectors, int recordCount) {
    for (ValueVector v : valueVectors) {
      allocateVector(v, v.getField().getName(), recordCount);
    }
  }

  public void allocateVector(ValueVector vector, String prefix, int recordCount) {
    String key = prefix + vector.getField().getName();
    AllocationHint hint = hints.get(key);
    if (vector instanceof AbstractMapVector) {
      allocateMap((AbstractMapVector) vector, prefix, recordCount, hint);
    } else {
      allocateVector(vector, recordCount, hint);
    }
//    Set<BufferLedger> ledgers = new HashSet<>();
//    vector.collectLedgers(ledgers);
//    int size = 0;
//    for (BufferLedger ledger : ledgers) {
//      size += ledger.getAccountedSize();
//    }
//    System.out.println(key + ": " + vector.getField().toString() +
//        " " +
//        ((hint == null) ? "no hint" : hint.toString()) +
//        ", " + size);
  }

  public void allocateVector(ValueVector vector, int recordCount, AllocationHint hint) {
    if (hint == null) {
      // Use hard-coded values. Same as ScanBatch

      AllocationHelper.allocate(vector, recordCount, 50, 10);
    } else {
      AllocationHelper.allocate(vector, recordCount, hint.entryWidth, hint.elementCount);
    }
  }

  private void allocateMap(AbstractMapVector map, String prefix, int recordCount, AllocationHint hint) {
    if (map instanceof AbstractRepeatedMapVector) {
      ((AbstractRepeatedMapVector) map).allocateOffsetsNew(recordCount);
      if (hint == null) {
        recordCount *= 10;
      } else {
        recordCount *= Math.round(hint.elementCount);
      }
    }
    prefix += map.getField().getName() + ".";
    for (ValueVector vector : map) {
      allocateVector(vector, prefix, recordCount);
    }
  }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder();
    buf.append("[" + getClass().getSimpleName())
       .append(" ");
    boolean first = true;
    for (Entry<String, AllocationHint>entry : hints.entrySet()) {
      if (! first) {
        buf.append(", ");
      }
      first = false;
      buf.append("[")
         .append(entry.getKey())
         .append(" ")
         .append(entry.getValue().toString())
         .append("]");
    }
    buf.append("]");
    return buf.toString();
  }
}
