/*
 * 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.parquet.thrift.struct;

import static org.apache.parquet.thrift.struct.ThriftTypeID.BOOL;
import static org.apache.parquet.thrift.struct.ThriftTypeID.BYTE;
import static org.apache.parquet.thrift.struct.ThriftTypeID.DOUBLE;
import static org.apache.parquet.thrift.struct.ThriftTypeID.ENUM;
import static org.apache.parquet.thrift.struct.ThriftTypeID.I16;
import static org.apache.parquet.thrift.struct.ThriftTypeID.I32;
import static org.apache.parquet.thrift.struct.ThriftTypeID.I64;
import static org.apache.parquet.thrift.struct.ThriftTypeID.LIST;
import static org.apache.parquet.thrift.struct.ThriftTypeID.MAP;
import static org.apache.parquet.thrift.struct.ThriftTypeID.SET;
import static org.apache.parquet.thrift.struct.ThriftTypeID.STRING;
import static org.apache.parquet.thrift.struct.ThriftTypeID.STRUCT;

import org.apache.parquet.schema.LogicalTypeAnnotation;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;


/**
 * Descriptor for a Thrift class.
 * Used to persist the thrift schema
 */
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "id")
@JsonSubTypes({
    @JsonSubTypes.Type(value=ThriftType.BoolType.class, name="BOOL"),
    @JsonSubTypes.Type(value=ThriftType.ByteType.class, name="BYTE"),
    @JsonSubTypes.Type(value=ThriftType.DoubleType.class, name="DOUBLE"),
    @JsonSubTypes.Type(value=ThriftType.EnumType.class, name="ENUM"),
    @JsonSubTypes.Type(value=ThriftType.I16Type.class, name="I16"),
    @JsonSubTypes.Type(value=ThriftType.I32Type.class, name="I32"),
    @JsonSubTypes.Type(value=ThriftType.I64Type.class, name="I64"),
    @JsonSubTypes.Type(value=ThriftType.ListType.class, name="LIST"),
    @JsonSubTypes.Type(value=ThriftType.MapType.class, name="MAP"),
    @JsonSubTypes.Type(value=ThriftType.SetType.class, name="SET"),
    @JsonSubTypes.Type(value=ThriftType.StringType.class, name="STRING"),
    @JsonSubTypes.Type(value=ThriftType.StructType.class, name="STRUCT")
})
public abstract class ThriftType {
  private LogicalTypeAnnotation logicalTypeAnnotation;

  public boolean hasLogicalTypeAnnotation() {
    return this.logicalTypeAnnotation != null;
  }

  public LogicalTypeAnnotation getLogicalTypeAnnotation() {
    return this.logicalTypeAnnotation;
  }

  public void setLogicalTypeAnnotation(LogicalTypeAnnotation logicalTypeAnnotation) {
    this.logicalTypeAnnotation = logicalTypeAnnotation;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof ThriftType)) return false;

    ThriftType that = (ThriftType) o;
    if (type != that.type) return false;

    return true;
  }

  @Override
  public int hashCode() {
    return type != null ? type.hashCode() : 0;
  }

  public static ThriftType fromJSON(String json) {
    return JSON.fromJSON(json, ThriftType.class);
  }

  public String toJSON() {
    return JSON.toJSON(this);
  }

  @Override
  public String toString() {
    return toJSON();
  }

  public interface StateVisitor<R, S> {

    R visit(MapType mapType, S state);

    R visit(SetType setType, S state);

    R visit(ListType listType, S state);

    R visit(StructType structType, S state);

    R visit(EnumType enumType, S state);

    R visit(BoolType boolType, S state);

    R visit(ByteType byteType, S state);

    R visit(DoubleType doubleType, S state);

    R visit(I16Type i16Type, S state);

    R visit(I32Type i32Type, S state);

    R visit(I64Type i64Type, S state);

    R visit(StringType stringType, S state);

  }

  /**
   * @deprecated will be removed in 2.0.0; use StateVisitor instead.
   */
  public interface TypeVisitor {

    void visit(MapType mapType);

    void visit(SetType setType);

    void visit(ListType listType);

    void visit(StructType structType);

    void visit(EnumType enumType);

    void visit(BoolType boolType);

    void visit(ByteType byteType);

    void visit(DoubleType doubleType);

    void visit(I16Type i16Type);

    void visit(I32Type i32Type);

    void visit(I64Type i64Type);

    void visit(StringType stringType);

  }

  /**
   * @deprecated will be removed in 2.0.0.
   */
  @Deprecated
  public static abstract class ComplexTypeVisitor implements TypeVisitor {

    @Override
    final public void visit(EnumType enumType) {
      throw new IllegalArgumentException("Expected complex type");
    }

    @Override
    final public void visit(BoolType boolType) {
      throw new IllegalArgumentException("Expected complex type");
    }

    @Override
    final public void visit(ByteType byteType) {
      throw new IllegalArgumentException("Expected complex type");
    }

    @Override
    final public void visit(DoubleType doubleType) {
      throw new IllegalArgumentException("Expected complex type");
    }

    @Override
    final public void visit(I16Type i16Type) {
      throw new IllegalArgumentException("Expected complex type");
    }

    @Override
    final public void visit(I32Type i32Type) {
      throw new IllegalArgumentException("Expected complex type");
    }

    @Override
    final public void visit(I64Type i64Type) {
      throw new IllegalArgumentException("Expected complex type");
    }

    @Override
    final public void visit(StringType stringType) {
      throw new IllegalArgumentException("Expected complex type");
    }

  }

  public static class StructType extends ThriftType {
    private final List<ThriftField> children;

    private final ThriftField[] childById;

  /**
   * Whether a struct is a union or a regular struct is not always known, because it was not always
   * written to the metadata files.
   *
   * We should always know this in the write path, but may not in the read path.
   */
   public enum StructOrUnionType {
      STRUCT,
      UNION,
      UNKNOWN
   }

    private final StructOrUnionType structOrUnionType;

    @Deprecated
    public StructType(List<ThriftField> children) {
      this(children, null);
    }

    @JsonCreator
    public StructType(@JsonProperty("children") List<ThriftField> children,
                      @JsonProperty("structOrUnionType") StructOrUnionType structOrUnionType) {
      super(STRUCT);
      this.structOrUnionType = structOrUnionType == null ? StructOrUnionType.STRUCT : structOrUnionType;
      this.children = children;
      int maxId = 0;
      if (children != null) {
        for (ThriftField thriftField : children) {
          maxId = Math.max(maxId, thriftField.getFieldId());
        }
        childById = new ThriftField[maxId + 1];
        for (ThriftField thriftField : children) {
          childById[thriftField.getFieldId()] = thriftField;
        }
      } else {
        childById = null;
      }
    }

    public List<ThriftField> getChildren() {
      return children;
    }

    @JsonIgnore
    public ThriftField getChildById(short id) {
      if (id >= childById.length) {
        return null;
      } else {
        return childById[id];
      }
    }

    @JsonProperty("structOrUnionType")
    public StructOrUnionType getStructOrUnionType() {
      return structOrUnionType;
    }

    @Override
    public <R, S> R accept(StateVisitor<R, S> visitor, S state) {
      return visitor.visit(this, state);
    }

    @Override
    public void accept(TypeVisitor visitor) {
      visitor.visit(this);
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;

      StructType that = (StructType) o;

      if (!Arrays.equals(childById, that.childById)) return false;
      return true;
    }

    @Override
    public int hashCode() {
      int result = childById != null ? Arrays.hashCode(childById) : 0;
      return result;
    }

  }

  public static class MapType extends ThriftType {
    private final ThriftField key;
    private final ThriftField value;

    @JsonCreator
    public MapType(@JsonProperty("key") ThriftField key, @JsonProperty("value") ThriftField value) {
      super(MAP);
      this.key = key;
      this.value = value;
    }

    public ThriftField getKey() {
      return key;
    }

    public ThriftField getValue() {
      return value;
    }

    @Override
    public <R, S> R accept(StateVisitor<R, S> visitor, S state) {
      return visitor.visit(this, state);
    }

    @Override
    public void accept(TypeVisitor visitor) {
      visitor.visit(this);
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (!(o instanceof MapType)) return false;
      if (!super.equals(o)) return false;

      MapType mapType = (MapType) o;

      if (!key.equals(mapType.key)) return false;
      if (!value.equals(mapType.value)) return false;

      return true;
    }

    @Override
    public int hashCode() {
      int result = super.hashCode();
      result = 31 * result + key.hashCode();
      result = 31 * result + value.hashCode();
      return result;
    }
  }

  public static class SetType extends ThriftType {
    private final ThriftField values;

    @JsonCreator
    public SetType(@JsonProperty("values") ThriftField values) {
      super(SET);
      this.values = values;
    }

    public ThriftField getValues() {
      return values;
    }

    @Override
    public <R, S> R accept(StateVisitor<R, S> visitor, S state) {
      return visitor.visit(this, state);
    }

    @Override
    public void accept(TypeVisitor visitor) {
      visitor.visit(this);
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (!(o instanceof SetType)) return false;
      if (!super.equals(o)) return false;

      SetType setType = (SetType) o;

      if (!values.equals(setType.values)) return false;

      return true;
    }

    @Override
    public int hashCode() {
      int result = super.hashCode();
      result = 31 * result + values.hashCode();
      return result;
    }
  }

  public static class ListType extends ThriftType {
    private final ThriftField values;

    @JsonCreator
    public ListType(@JsonProperty("values") ThriftField values) {
      super(LIST);
      this.values = values;
    }

    public ThriftField getValues() {
      return values;
    }

    @Override
    public <R, S> R accept(StateVisitor<R, S> visitor, S state) {
      return visitor.visit(this, state);
    }

    @Override
    public void accept(TypeVisitor visitor) {
      visitor.visit(this);
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (!(o instanceof ListType)) return false;
      if (!super.equals(o)) return false;

      ListType listType = (ListType) o;

      if (!values.equals(listType.values)) return false;

      return true;
    }

    @Override
    public int hashCode() {
      int result = super.hashCode();
      result = 31 * result + values.hashCode();
      return result;
    }
  }

  public static class EnumValue {
    private final int id;
    private final String name;

    @JsonCreator
    public EnumValue(@JsonProperty("id") int id, @JsonProperty("name") String name) {
      super();
      this.id = id;
      this.name = name;
    }
    public int getId() {
      return id;
    }
    public String getName() {
      return name;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (!(o instanceof EnumValue)) return false;

      EnumValue enumValue = (EnumValue) o;

      if (id != enumValue.id) return false;
      if (name != null ? !name.equals(enumValue.name) : enumValue.name != null) return false;

      return true;
    }

    @Override
    public int hashCode() {
      int result = id;
      result = 31 * result + (name != null ? name.hashCode() : 0);
      return result;
    }
  }

  public static class EnumType extends ThriftType {
    private final List<EnumValue> values;
    private Map<Integer,EnumValue> idEnumLookup;
    @JsonCreator
    public EnumType(@JsonProperty("values") List<EnumValue> values) {
      super(ENUM);
      this.values = values;
    }

    public Iterable<EnumValue> getValues() {
      return new Iterable<EnumValue>() {
        @Override
        public Iterator<EnumValue> iterator() {
          return values.iterator();
        }
      };
    }

    public EnumValue getEnumValueById(int id) {
      prepareEnumLookUp();
      return idEnumLookup.get(id);
    }

    private void prepareEnumLookUp() {
      if (idEnumLookup == null) {
        idEnumLookup=new HashMap<Integer, EnumValue>();
        for (EnumValue value : values) {
          idEnumLookup.put(value.getId(),value);
        }
      }
    }

    @Override
    public <R, S> R accept(StateVisitor<R, S> visitor, S state) {
      return visitor.visit(this, state);
    }

    @Override
    public void accept(TypeVisitor visitor) {
      visitor.visit(this);
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (!(o instanceof EnumType)) return false;
      if (!super.equals(o)) return false;

      EnumType enumType = (EnumType) o;

      if (!values.equals(enumType.values)) return false;

      return true;
    }

    @Override
    public int hashCode() {
      int result = super.hashCode();
      result = 31 * result + values.hashCode();
      return result;
    }
  }

  public static class BoolType extends ThriftType {

    @JsonCreator
    public BoolType() {
      super(BOOL);
    }
    @Override
    public <R, S> R accept(StateVisitor<R, S> visitor, S state) {
      return visitor.visit(this, state);
    }

    @Override
    public void accept(TypeVisitor visitor) {
      visitor.visit(this);
    }
  }

  public static class ByteType extends ThriftType {

    @JsonCreator
    public ByteType() {
      super(BYTE);
    }
    @Override
    public <R, S> R accept(StateVisitor<R, S> visitor, S state) {
      return visitor.visit(this, state);
    }

    @Override
    public void accept(TypeVisitor visitor) {
      visitor.visit(this);
    }
  }

  public static class DoubleType extends ThriftType {

    @JsonCreator
    public DoubleType() {
      super(DOUBLE);
    }
    @Override
    public <R, S> R accept(StateVisitor<R, S> visitor, S state) {
      return visitor.visit(this, state);
    }

    @Override
    public void accept(TypeVisitor visitor) {
      visitor.visit(this);
    }
  }

  public static class I16Type extends ThriftType {

    @JsonCreator
    public I16Type() {
      super(I16);
    }
    @Override
    public <R, S> R accept(StateVisitor<R, S> visitor, S state) {
      return visitor.visit(this, state);
    }

    @Override
    public void accept(TypeVisitor visitor) {
      visitor.visit(this);
    }
  }

  public static class I32Type extends ThriftType {

    @JsonCreator
    public I32Type() {
      super(I32);
    }
    @Override
    public <R, S> R accept(StateVisitor<R, S> visitor, S state) {
      return visitor.visit(this, state);
    }

    @Override
    public void accept(TypeVisitor visitor) {
      visitor.visit(this);
    }
  }

  public static class I64Type extends ThriftType {

    @JsonCreator
    public I64Type() {
      super(I64);
    }

    @Override
    public <R, S> R accept(StateVisitor<R, S> visitor, S state) {
      return visitor.visit(this, state);
    }


    @Override
    public void accept(TypeVisitor visitor) {
      visitor.visit(this);
    }
  }

  public static class StringType extends ThriftType {
    private boolean binary = false;

    @JsonCreator
    public StringType() {
      super(STRING);
    }

    public boolean isBinary() {
      return binary;
    }

    public void setBinary(boolean binary) {
      this.binary = binary;
    }

    @Override
    public <R, S> R accept(StateVisitor<R, S> visitor, S state) {
      return visitor.visit(this, state);
    }

    @Override
    public void accept(TypeVisitor visitor) {
      visitor.visit(this);
    }
  }

  private final ThriftTypeID type;

  private ThriftType(ThriftTypeID type) {
    super();
    this.type = type;
  }

  public abstract void accept(TypeVisitor visitor);

  public abstract <R, S> R accept(StateVisitor<R, S> visitor, S state);

  @JsonIgnore
  public ThriftTypeID getType() {
    return this.type;
  }

}
