/*
 * 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.vector.accessor.writer;

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

import org.apache.drill.exec.record.metadata.ColumnMetadata;
import org.apache.drill.exec.vector.accessor.ColumnReader;
import org.apache.drill.exec.vector.accessor.ColumnWriterIndex;
import org.apache.drill.exec.vector.accessor.writer.AbstractArrayWriter.ArrayObjectWriter;
import org.apache.drill.exec.vector.accessor.writer.dummy.DummyArrayWriter;
import org.apache.drill.exec.vector.complex.AbstractMapVector;
import org.apache.drill.exec.vector.complex.MapVector;
import org.apache.drill.exec.vector.complex.RepeatedMapVector;

/**
 * Writer for a Drill Map type. Maps are actually tuples, just like rows.
 */
public abstract class MapWriter extends AbstractTupleWriter {

  /**
   * Writer for a single (non-array) map. Clients don't really "write" maps;
   * rather, this writer is a holder for the columns within the map, and those
   * columns are what is written.
   */
  protected static class SingleMapWriter extends MapWriter {
    private final MapVector mapVector;

    protected SingleMapWriter(ColumnMetadata schema, MapVector vector, List<AbstractObjectWriter> writers) {
      super(schema, writers);
      mapVector = vector;
    }

    @Override
    public void endWrite() {
      super.endWrite();

      // A non repeated map has a field that holds the value count.
      // Update it. (A repeated map uses the offset vector's value count.)
      // Special form of set value count: used only for
      // this class to avoid setting the value count of children.
      // Setting these counts was already done. Doing it again
      // will corrupt nullable vectors because the writers don't
      // set the "lastSet" field of nullable vector accessors,
      // and the initial value of -1 will cause all values to
      // be overwritten.

      mapVector.setMapValueCount(vectorIndex.vectorIndex());
    }

    @Override
    public void preRollover() {
      super.preRollover();
      mapVector.setMapValueCount(vectorIndex.rowStartIndex());
    }

    @Override
    public boolean isProjected() { return true; }
  }

  /**
   * Writer for a an array of maps. A single array index coordinates writes
   * to the constituent member vectors so that, say, the values for (row 10,
   * element 5) all occur to the same position in the columns within the map.
   * Since the map is an array, it has an associated offset vector, which the
   * parent array writer is responsible for maintaining.
   */
  protected static class ArrayMapWriter extends MapWriter {

    protected ArrayMapWriter(ColumnMetadata schema, List<AbstractObjectWriter> writers) {
      super(schema, writers);
    }

    @Override
    public void bindIndex(ColumnWriterIndex index) {

      // This is a repeated map, so the provided index is an array element
      // index. Convert this to an index that will not increment the element
      // index on each write so that a map with three members, say, won't
      // increment the index for each member. Rather, the index must be
      // incremented at the array level.

      bindIndex(index, new MemberWriterIndex(index));
    }

    @Override
    public boolean isProjected() { return true; }
  }

  protected static class DummyMapWriter extends MapWriter {

    protected DummyMapWriter(ColumnMetadata schema,
        List<AbstractObjectWriter> writers) {
      super(schema, writers);
    }

    @Override
    public boolean isProjected() { return false; }

    @Override
    public void copy(ColumnReader from) { }
  }

  protected static class DummyArrayMapWriter extends MapWriter {

    protected DummyArrayMapWriter(ColumnMetadata schema,
        List<AbstractObjectWriter> writers) {
      super(schema, writers);
    }

    @Override
    public boolean isProjected() { return false; }

    @Override
    public void copy(ColumnReader from) { }
  }

  protected final ColumnMetadata mapColumnSchema;

  protected MapWriter(ColumnMetadata schema, List<AbstractObjectWriter> writers) {
    super(schema.tupleSchema(), writers);
    mapColumnSchema = schema;
  }

  public static TupleObjectWriter buildMap(ColumnMetadata schema, MapVector vector,
      List<AbstractObjectWriter> writers) {
    MapWriter mapWriter;
    if (vector != null) {

      // Vector is not required for a map writer; the map's columns
      // are written, but not the (non-array) map.

      mapWriter = new SingleMapWriter(schema, vector, writers);
    } else {
      mapWriter = new DummyMapWriter(schema, writers);
    }
    return new TupleObjectWriter(mapWriter);
  }

  public static ArrayObjectWriter buildMapArray(ColumnMetadata schema,
      RepeatedMapVector mapVector,
      List<AbstractObjectWriter> writers) {
    MapWriter mapWriter;
    if (mapVector != null) {
      mapWriter = new ArrayMapWriter(schema, writers);
    } else {
      mapWriter = new DummyArrayMapWriter(schema, writers);
    }
    TupleObjectWriter mapArray = new TupleObjectWriter(mapWriter);
    AbstractArrayWriter arrayWriter;
    if (mapVector != null) {
      arrayWriter = new ObjectArrayWriter(schema,
          mapVector.getOffsetVector(),
          mapArray);
    } else  {
      arrayWriter = new DummyArrayWriter(schema, mapArray);
    }
    return new ArrayObjectWriter(arrayWriter);
  }

  public static AbstractObjectWriter buildMapWriter(ColumnMetadata schema,
      AbstractMapVector vector,
      List<AbstractObjectWriter> writers) {
    if (schema.isArray()) {
      return MapWriter.buildMapArray(schema,
          (RepeatedMapVector) vector, writers);
    } else {
      return MapWriter.buildMap(schema, (MapVector) vector, writers);
    }
  }

  public static AbstractObjectWriter buildMapWriter(ColumnMetadata schema, AbstractMapVector vector) {
    assert schema.tupleSchema().size() == 0;
    return buildMapWriter(schema, vector, new ArrayList<AbstractObjectWriter>());
  }

  @Override
  public ColumnMetadata schema() { return mapColumnSchema; }
}
