/*
 * 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.carbondata.core.writer.sortindex;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.carbondata.core.constants.CarbonCommonConstants;
import org.apache.carbondata.core.metadata.datatype.DataType;
import org.apache.carbondata.core.metadata.datatype.DataTypes;
import org.apache.carbondata.core.util.CarbonUtil;

/**
 * Dictionary sort model class holds the member byte value and corresponding key value.
 */
public class CarbonDictionarySortModel implements Comparable<CarbonDictionarySortModel> {

  /**
   * Surrogate key
   */
  private int key;

  /**
   * member value in bytes
   */
  private String memberValue;

  /**
   * member dataType
   */
  private DataType dataType;

  /**
   * Constructor to init the dictionary sort model
   *
   * @param key
   * @param dataType
   * @param memberValue
   */
  public CarbonDictionarySortModel(int key, DataType dataType, String memberValue) {
    this.key = key;
    this.dataType = dataType;
    this.memberValue = memberValue;
  }

  /**
   * Compare
   */
  @Override
  public int compareTo(CarbonDictionarySortModel o) {
    if (dataType == DataTypes.SHORT ||
        dataType == DataTypes.INT ||
        dataType == DataTypes.LONG ||
        dataType == DataTypes.DOUBLE) {
      Double d1 = null;
      Double d2 = null;
      try {
        d1 = new Double(memberValue);
      } catch (NumberFormatException e) {
        if (CarbonCommonConstants.MEMBER_DEFAULT_VAL.equals(o.memberValue)) {
          return -1;
        }
        return 1;
      }
      try {
        d2 = new Double(o.memberValue);
      } catch (NumberFormatException e) {
        return -1;
      }
      return d1.compareTo(d2);
    } else if (DataTypes.isDecimal(dataType)) {
      java.math.BigDecimal val1 = null;
      java.math.BigDecimal val2 = null;
      try {
        val1 = new java.math.BigDecimal(memberValue);
      } catch (NumberFormatException e) {
        if (CarbonCommonConstants.MEMBER_DEFAULT_VAL.equals(o.memberValue)) {
          return -1;
        }
        return 1;
      }
      try {
        val2 = new java.math.BigDecimal(o.memberValue);
      } catch (NumberFormatException e) {
        return -1;
      }
      return val1.compareTo(val2);
    } else if (dataType == DataTypes.DATE || dataType == DataTypes.TIMESTAMP) {
      String format = CarbonUtil.getFormatFromProperty(dataType);
      SimpleDateFormat parser = new SimpleDateFormat(format);
      Date date1 = null;
      Date date2 = null;
      try {
        date1 = parser.parse(memberValue);
      } catch (ParseException e) {
        if (CarbonCommonConstants.MEMBER_DEFAULT_VAL.equals(o.memberValue)) {
          return -1;
        }
        return 1;
      }
      try {
        date2 = parser.parse(o.memberValue);
      } catch (ParseException e) {
        return -1;
      }
      return date1.compareTo(date2);
    } else {
      return this.memberValue.compareTo(o.memberValue);
    }
  }

  /**
   * @see Object#hashCode()
   */
  @Override
  public int hashCode() {
    return ((memberValue == null) ? 0 : memberValue.hashCode());
  }

  /**
   * @see Object#equals(Object)
   */
  @Override
  public boolean equals(Object obj) {
    if (obj instanceof CarbonDictionarySortModel) {
      if (this == obj) {
        return true;
      }
      CarbonDictionarySortModel other = (CarbonDictionarySortModel) obj;
      if (memberValue == null) {
        if (other.memberValue != null) {
          return false;
        }
      } else if (!this.memberValue.equals(other.memberValue)) {
        return false;
      }
      return true;
    } else {
      return false;
    }
  }

  /**
   * return the surrogate of the member
   *
   * @return
   */
  public int getKey() {
    return key;
  }

}
