/*
 * 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 org.apache.drill.common.types.TypeProtos.MinorType;
import org.apache.drill.exec.record.MaterializedField;
import org.apache.drill.exec.record.metadata.ColumnMetadata;
import org.apache.drill.exec.vector.UInt4Vector;
import org.apache.drill.exec.vector.accessor.ArrayWriter;
import org.apache.drill.exec.vector.complex.RepeatedListVector;

/**
 * Implements a writer for a repeated list. A repeated list is really
 * an array of arrays. It is an "array" because it does not support
 * nulls. (The Drill [non-repeated] "list vector" does support nulls.)
 * The terminology is confusing, but it is what Drill has settled upon.
 * <p>
 * Because repeated lists can be nested, they support incremental
 * construction. Build the outer array, then the inner, then the leaf
 * to build a 3D array. Since building is incremental, this form of
 * array must track state and use the state to keep the newly-added
 * element writer in sync.
 * <p>
 * To keep things (relatively) simple, the repeated list array starts
 * out with an inner list. For the row set writer, the inner list
 * is the actual element writer. For the result set loader, the inner
 * list is a dummy, to be replaced by the real one once it is discovered
 * by reading data (or by parsing a schema.)
 */
public class RepeatedListWriter extends ObjectArrayWriter {

  public interface ArrayListener {

    AbstractObjectWriter setChild(ArrayWriter array, ColumnMetadata column);

    AbstractObjectWriter setChild(ArrayWriter array, MaterializedField field);
  }

  private State state = State.IDLE;
  private ArrayListener listener;

  protected RepeatedListWriter(ColumnMetadata schema, UInt4Vector offsetVector,
      AbstractObjectWriter elementWriter) {
    super(schema, offsetVector, elementWriter);
  }

  public static AbstractObjectWriter buildRepeatedList(ColumnMetadata schema,
      RepeatedListVector vector, AbstractObjectWriter elementWriter) {
    AbstractArrayWriter arrayWriter = new RepeatedListWriter(schema,
        vector == null ? null : vector.getOffsetVector(),
        elementWriter);
    return new ArrayObjectWriter(arrayWriter);
  }

  public void bindListener(ArrayListener listener) {
    this.listener = listener;
  }

  public AbstractObjectWriter defineElement(MaterializedField schema) {
    if (listener == null || elementObjWriter.schema().type() != MinorType.NULL) {
      throw new UnsupportedOperationException();
    } else {
      return replaceChild(listener.setChild(this, schema));
    }
  }

  public AbstractObjectWriter defineElement(ColumnMetadata schema) {
    if (listener == null || elementObjWriter.schema().type() != MinorType.NULL) {
      throw new UnsupportedOperationException();
    } else {
      return replaceChild(listener.setChild(this, schema));
    }
  }

  private AbstractObjectWriter replaceChild(AbstractObjectWriter newChild) {
    elementObjWriter = newChild;
    elementObjWriter.events().bindIndex(elementIndex);
    if (state != State.IDLE) {
      elementObjWriter.events().startWrite();
      if (state == State.IN_ROW) {
        elementObjWriter.events().startRow();
      }
    }
    return elementObjWriter;
  }

  @Override
  public void startWrite() {
    assert state == State.IDLE;
    state = State.IN_WRITE;
    super.startWrite();
  }

  @Override
  public void startRow() {
    assert state == State.IN_WRITE;
    state = State.IN_ROW;
    super.startRow();
  }

  @Override
  public void saveRow() {
    assert state == State.IN_ROW;
    super.saveRow();
    state = State.IN_WRITE;
  }

  @Override
  public void endWrite() {
    assert state != State.IDLE;
    super.endWrite();
    state = State.IDLE;
  }
}
