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

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.AbstractCollection;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configurable;
import org.apache.hadoop.conf.Configuration;

/** A Writable wrapper for EnumSet. */
@InterfaceAudience.Public
@InterfaceStability.Stable
public class EnumSetWritable<E extends Enum<E>> extends AbstractCollection<E>
  implements Writable, Configurable  {

  private EnumSet<E> value;

  private transient Class<E> elementType;

  private transient Configuration conf;
  
  EnumSetWritable() {
  }

  @Override
  public Iterator<E> iterator() { return value.iterator(); }
  @Override
  public int size() { return value.size(); }
  @Override
  public boolean add(E e) {
    if (value == null) {
      value = EnumSet.of(e);
      set(value, null);
    }
    return value.add(e);
  }

  /**
   * Construct a new EnumSetWritable. If the <tt>value</tt> argument is null or
   * its size is zero, the <tt>elementType</tt> argument must not be null. If
   * the argument <tt>value</tt>'s size is bigger than zero, the argument
   * <tt>elementType</tt> is not be used.
   * 
   * @param value
   * @param elementType
   */
  public EnumSetWritable(EnumSet<E> value, Class<E> elementType) {
    set(value, elementType);
  }

  /**
   * Construct a new EnumSetWritable. Argument <tt>value</tt> should not be null
   * or empty.
   * 
   * @param value
   */
  public EnumSetWritable(EnumSet<E> value) {
    this(value, null);
  }

  /**
   * reset the EnumSetWritable with specified
   * <tt>value</value> and <tt>elementType</tt>. If the <tt>value</tt> argument
   * is null or its size is zero, the <tt>elementType</tt> argument must not be
   * null. If the argument <tt>value</tt>'s size is bigger than zero, the
   * argument <tt>elementType</tt> is not be used.
   * 
   * @param value
   * @param elementType
   */
  public void set(EnumSet<E> value, Class<E> elementType) {
    if ((value == null || value.size() == 0)
        && (this.elementType == null && elementType == null)) {
      throw new IllegalArgumentException(
          "The EnumSet argument is null, or is an empty set but with no elementType provided.");
    }
    this.value = value;
    if (value != null && value.size() > 0) {
      Iterator<E> iterator = value.iterator();
      this.elementType = iterator.next().getDeclaringClass();
    } else if (elementType != null) {
      this.elementType = elementType;
    }
  }

  /** Return the value of this EnumSetWritable. */
  public EnumSet<E> get() {
    return value;
  }

  @Override
  @SuppressWarnings("unchecked")
  public void readFields(DataInput in) throws IOException {
    int length = in.readInt();
    if (length == -1)
      this.value = null;
    else if (length == 0) {
      this.elementType = (Class<E>) ObjectWritable.loadClass(conf,
          WritableUtils.readString(in));
      this.value = EnumSet.noneOf(this.elementType);
    } else {
      E first = (E) ObjectWritable.readObject(in, conf);
      this.value = (EnumSet<E>) EnumSet.of(first);
      for (int i = 1; i < length; i++)
        this.value.add((E) ObjectWritable.readObject(in, conf));
    }
  }

  @Override
  public void write(DataOutput out) throws IOException {
    if (this.value == null) {
      out.writeInt(-1);
      WritableUtils.writeString(out, this.elementType.getName());
    } else {
      Object[] array = this.value.toArray();
      int length = array.length;
      out.writeInt(length);
      if (length == 0) {
        if (this.elementType == null)
          throw new UnsupportedOperationException(
              "Unable to serialize empty EnumSet with no element type provided.");
        WritableUtils.writeString(out, this.elementType.getName());
      }
      for (int i = 0; i < length; i++) {
        ObjectWritable.writeObject(out, array[i], array[i].getClass(), conf);
      }
    }
  }

  /**
   * Returns true if <code>o</code> is an EnumSetWritable with the same value,
   * or both are null.
   */
  @Override
  public boolean equals(Object o) {
    if (o == null) {
      throw new IllegalArgumentException("null argument passed in equal().");
    }

    if (!(o instanceof EnumSetWritable))
      return false;

    EnumSetWritable<?> other = (EnumSetWritable<?>) o;

    if (this == o || (this.value == other.value))
      return true;
    if (this.value == null) // other.value must not be null if we reach here
      return false;

    return this.value.equals(other.value);
  }

  /**
   * Returns the class of all the elements of the underlying EnumSetWriable. It
   * may return null.
   * 
   * @return the element class
   */
  public Class<E> getElementType() {
    return elementType;
  }

  @Override
  public int hashCode() {
    if (value == null)
      return 0;
    return (int) value.hashCode();
  }

  @Override
  public String toString() {
    if (value == null)
      return "(null)";
    return value.toString();
  }

  @Override
  public Configuration getConf() {
    return this.conf;
  }

  @Override
  public void setConf(Configuration conf) {
    this.conf = conf;
  }

  static {
    WritableFactories.setFactory(EnumSetWritable.class, new WritableFactory() {
      @SuppressWarnings("unchecked")
      @Override
      public Writable newInstance() {
        return new EnumSetWritable();
      }
    });
  }
}
