/*
 * 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 org.apache.drill.exec.exception.SchemaChangeException;
import org.apache.drill.exec.proto.UserBitShared.SerializedField;
import org.apache.drill.exec.record.BatchSchema.SelectionVectorMode;

import com.google.common.collect.Lists;

/**
 * A reusable builder that supports the creation of BatchSchemas. Can have a supporting expected object. If the expected Schema object is defined, the
 * builder will always check that this schema is a equal or more materialized version of the current schema.
 */
public class SchemaBuilder {
  private List<MaterializedField> fields = Lists.newArrayList();

  private BatchSchema.SelectionVectorMode selectionVectorMode = SelectionVectorMode.NONE;

  SchemaBuilder() {
  }

//  /**
//   * Add a field where we don't have type information. In this case, DataType will be set to LATEBIND and valueClass
//   * will be set to null.
//   *
//   * @param fieldId
//   *          The desired fieldId. Should be unique for this BatchSchema.
//   * @param nullable
//   *          Whether this field supports nullability.
//   * @param mode
//   * @throws SchemaChangeException
//   */
//  public void addLateBindField(short fieldId, boolean nullable, ValueMode mode) throws SchemaChangeException {
//    addTypedField(fieldId, DataType.LATEBIND, nullable, mode, Void.class);
//  }

  public SchemaBuilder setSelectionVectorMode(BatchSchema.SelectionVectorMode selectionVectorMode) {
    this.selectionVectorMode = selectionVectorMode;
    return this;
  }

  public SchemaBuilder addFields(Iterable<MaterializedField> fields) {
    for (MaterializedField f : fields) {
      addField(f);
    }
    return this;
  }

  public SchemaBuilder addSerializedFields(Iterable<SerializedField> fields) {
    for (SerializedField f : fields) {
      addField(MaterializedField.create(f));
    }
    return this;
  }

//  private void setTypedField(short fieldId, DataType type, boolean nullable, ValueMode mode, Class<?> valueClass)
//      throws SchemaChangeException {
//    MaterializedField f = new MaterializedField(fieldId, type, nullable, mode, valueClass);
//    if (expectedFields != null) {
//      if (!expectedFields.containsKey(f.getFieldId()))
//        throw new SchemaChangeException(
//            String
//                .format(
//                    "You attempted to add a field for Id An attempt was made to add a duplicate fieldId to the schema.  The offending fieldId was %d",
//                    fieldId));
//      f.checkMaterialization(expectedFields.lget()); // TODO: lget is not safe if expectedFields is shared
//    }
//    fields.put(f.getFieldId(), f);
//  }

  public SchemaBuilder addField(MaterializedField f) {
    fields.add(f);
    return this;
  }

//  public void addTypedField(short fieldId, DataType type, boolean nullable, ValueMode mode, Class<?> valueClass)
//      throws SchemaChangeException {
//    if (fields.containsKey(fieldId))
//      throw new SchemaChangeException(String.format(
//          "An attempt was made to add a duplicate fieldId to the schema.  The offending fieldId was %d", fieldId));
//    setTypedField(fieldId, type, nullable, mode, valueClass);
//  }
//
//  public void replaceTypedField(short fieldId, DataType type, boolean nullable, ValueMode mode, Class<?> valueClass)
//      throws SchemaChangeException {
//    if (!fields.containsKey(fieldId))
//      throw new SchemaChangeException(
//          String.format("An attempt was made to replace a field in the schema, however the schema does " +
//              "not currently contain that field id.  The offending fieldId was %d", fieldId));
//    setTypedField(fieldId, type, nullable, mode, valueClass);
//  }

  public SchemaBuilder removeField(MaterializedField f) throws SchemaChangeException {
    if (!fields.remove(f)) {
      throw new SchemaChangeException("You attempted to remove an nonexistent field.");
    }
    return this;
  }

  /**
   * Generate a new BatchSchema object based on the current state of the builder.
   * @return
   * @throws SchemaChangeException
   */
  public BatchSchema build() {
    List<MaterializedField> fieldList = Lists.newArrayList(fields);
    return new BatchSchema(this.selectionVectorMode, fieldList);
  }

}
