/*
 * 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.geode.cache.query.internal.types;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Arrays;

import org.apache.geode.DataSerializer;
import org.apache.geode.cache.query.Struct;
import org.apache.geode.cache.query.internal.StructImpl;
import org.apache.geode.cache.query.types.ObjectType;
import org.apache.geode.cache.query.types.StructType;
import org.apache.geode.internal.serialization.DeserializationContext;
import org.apache.geode.internal.serialization.SerializationContext;

/**
 * Implementation of StructType
 *
 * @since GemFire 4.0
 */
public class StructTypeImpl extends ObjectTypeImpl implements StructType {
  private static final long serialVersionUID = -6368710865627039204L;
  private String[] fieldNames;
  private ObjectType[] fieldTypes;
  private String[] indexAlternativeFieldNames;

  /**
   * Empty constructor to satisfy <code>DataSerializer</code> requirements
   */
  public StructTypeImpl() {}

  /** Creates a new instance of StructType */
  public StructTypeImpl(String[] fieldNames) {
    this(fieldNames, null);
  }

  public StructTypeImpl(String[] fieldNames, ObjectType[] fieldTypes) {
    this(Struct.class, fieldNames, fieldTypes);
  }

  public StructTypeImpl(String[] fieldNames, String[] indexAlternativeFieldNames,
      ObjectType[] fieldTypes) {
    this(Struct.class, fieldNames, fieldTypes);
    this.indexAlternativeFieldNames = indexAlternativeFieldNames;
  }

  // supply actual implementation class, handles Region.Entry case
  // where Region.Entry acts like a Struct with extra protocol (e.g. getStatistics, etc.)
  // By using a StructType, we get access to key and value types as well as the
  // Region.Entry properties.
  public StructTypeImpl(Class clazz, String[] fieldNames, ObjectType[] fieldTypes) {
    super(clazz);
    if (fieldNames == null) {
      throw new IllegalArgumentException(
          "fieldNames must not be null");
    }
    this.fieldNames = fieldNames;
    this.fieldTypes = fieldTypes == null ? new ObjectType[this.fieldNames.length] : fieldTypes;
    for (int i = 0; i < this.fieldTypes.length; i++) {
      if (this.fieldTypes[i] == null) {
        this.fieldTypes[i] = TypeUtils.getObjectType(Object.class);
      }
    }
  }


  @Override
  public ObjectType[] getFieldTypes() {
    return this.fieldTypes;
  }

  @Override
  public String[] getFieldNames() {
    return this.fieldNames;
  }

  @Override
  public int getFieldIndex(String fieldName) {
    for (int i = 0; i < this.fieldNames.length; i++) {
      if (this.fieldNames[i].equals(fieldName)) {
        return i;
      }
    }
    throw new IllegalArgumentException(
        String.format("fieldName %s not found", fieldName));
  }

  @Override
  public boolean equals(Object obj) {
    if (!(obj instanceof StructTypeImpl))
      return false;
    StructTypeImpl t = (StructTypeImpl) obj;
    return (Arrays.equals(this.fieldNames, t.getFieldNames())
        || Arrays.equals(this.indexAlternativeFieldNames, t.getFieldNames()))
        && Arrays.equals(getFieldTypes(), t.getFieldTypes());
  }

  @Override
  public int hashCode() {
    return Arrays.hashCode(fieldNames) ^ Arrays.hashCode(fieldTypes);
  }

  @Override
  public String toString() {
    StringBuffer sb = new StringBuffer("struct<");
    for (int i = 0; i < fieldNames.length; i++) {
      if (i > 0)
        sb.append(',');
      sb.append(fieldNames[i] + ":" + fieldTypes[i]);
    }
    sb.append('>');
    return sb.toString();
  }

  @Override
  public boolean isCollectionType() {
    return false;
  }

  @Override
  public boolean isMapType() {
    return false;
  }

  @Override
  public boolean isStructType() {
    return true;
  }


  // Static Utilities
  public static StructTypeImpl typeFromStruct(Struct s) {
    // handle unlikely event that Struct is not a StructImpl
    if (s instanceof StructImpl) {
      return (StructTypeImpl) s.getStructType();
    }
    return new StructTypeImpl(s.getStructType().getFieldNames(), s.getStructType().getFieldTypes());
  }

  @Override
  public int getDSFID() {
    return STRUCT_TYPE_IMPL;
  }

  @Override
  public void fromData(DataInput in,
      DeserializationContext context) throws IOException, ClassNotFoundException {
    super.fromData(in, context);
    this.fieldNames = DataSerializer.readStringArray(in);
    this.fieldTypes = (ObjectType[]) DataSerializer.readObjectArray(in);
  }

  @Override
  public void toData(DataOutput out,
      SerializationContext context) throws IOException {
    super.toData(out, context);
    DataSerializer.writeStringArray(this.fieldNames, out);
    DataSerializer.writeObjectArray(fieldTypes, out);
  }

}
