/*
 * 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.metadata.ColumnMetadata;
import org.apache.drill.exec.vector.accessor.ColumnWriterIndex;
import org.apache.drill.exec.vector.accessor.ObjectWriter;
import org.apache.drill.exec.vector.accessor.impl.HierarchicalFormatter;
import org.apache.drill.exec.vector.accessor.writer.UnionWriterImpl.UnionShim;
import com.google.common.base.Preconditions;

/**
 * Shim for a list that holds a single type, but may eventually become a
 * list of variants. (A list that is declared to hold a single type
 * is implemented using the {@link ListWriterImpl} class that
 * directly holds that single type.) This shim is needed when we want
 * to present a uniform variant interface for a list that holds zero
 * one (this case) or many types.
 */

public class SimpleListShim implements UnionShim {

  private UnionWriterImpl writer;
  private AbstractObjectWriter colWriter;

  public SimpleListShim() { }

  public SimpleListShim(AbstractObjectWriter writer) {
    this.colWriter = writer;
  }

  @Override
  public void bindWriter(UnionWriterImpl writer) {
    this.writer = writer;
  }

  @Override
  public void bindIndex(ColumnWriterIndex index) {
    events().bindIndex(index);
  }

  @Override
  public void bindListener(ColumnWriterListener listener) {
    colWriter.events().bindListener(listener);
  }

  @Override
  public boolean hasType(MinorType type) {
    return type == colWriter.schema().type();
  }

  @Override
  public void setType(MinorType type) {
    if (! hasType(type)) {

      // Not this type. Ask the listener to promote this writer
      // to a union, then ask the writer to set the type on
      // the resulting new shim.

      addMember(type);
      writer.setType(type);
    }
  }

  @Override
  public ObjectWriter member(MinorType type) {
    if (hasType(type)) {
      return colWriter;
    }
    return addMember(type);
  }

  public AbstractObjectWriter memberWriter() {
    return colWriter;
  }

  @Override
  public AbstractObjectWriter addMember(ColumnMetadata colSchema) {
    return doAddMember((AbstractObjectWriter) writer.listener().addMember(colSchema));
  }

  @Override
  public AbstractObjectWriter addMember(MinorType type) {
    return doAddMember((AbstractObjectWriter) writer.listener().addType(type));
  }

  /**
   * This is a bit of magic. The listener will create the writer (and vector) for
   * the requested type. It will also replace the shim in the writer with something
   * that handles a union, so that, when the listener returns,
   * this shim is no longer bound to the writer. Our dying act is to ask the
   * new shim to add the new writer as a member. The listener must have moved our
   * existing reader to the new union shim; but we must add the new writer.
   *
   * @param colWriter the column writer returned from the listener
   * @return the same column writer
   */

  private AbstractObjectWriter doAddMember(AbstractObjectWriter colWriter) {
    // Something went terribly wrong if the check below fails.
    Preconditions.checkState(writer.shim() != this);
    writer.shim().addMember(colWriter);
    return colWriter;
  }

  @Override
  public void addMember(AbstractObjectWriter colWriter) {

    // Should only be called when promoting from a no-type shim to this
    // single type shim. Otherwise, something is wrong with the type
    // promotion logic.

    Preconditions.checkState(this.colWriter == null);
    this.colWriter = colWriter;
    writer.addMember(colWriter);
  }

  @Override
  public void setNull() {
    colWriter.setNull();
  }

  private WriterEvents events() { return colWriter.events(); }

  @Override
  public void startWrite() {

    // startWrite called before the column is added.

    if (colWriter != null) {
      colWriter.events().startWrite();
    }
  }

  @Override
  public void startRow() {

    // startRow called before the column is added.

    if (colWriter != null) {
      colWriter.events().startRow();
    }
  }

  @Override
  public void endArrayValue() {
    events().endArrayValue();
  }

  @Override
  public void restartRow() {
    events().restartRow();
  }

  @Override
  public void saveRow() {
    events().saveRow();
  }

  @Override
  public void endWrite() {
    events().endWrite();
  }

  @Override
  public void preRollover() {
    events().preRollover();
  }

  @Override
  public void postRollover() {
    events().postRollover();
  }

  @Override
  public int lastWriteIndex() {
    return events().lastWriteIndex();
  }

  @Override
  public int rowStartIndex() {
    return events().rowStartIndex();
  }

  @Override
  public int writeIndex() {
    return events().writeIndex();
  }

  @Override
  public void dump(HierarchicalFormatter format) {
    format.startObject(this).attribute("colWriter");
    colWriter.dump(format);
    format.endObject();
  }
}
