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

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

import org.apache.carbondata.common.logging.LogServiceFactory;
import org.apache.carbondata.core.constants.CarbonCommonConstants;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

/*
  Prior to Carbon 1.3 the the loadMetaData @timestamp and @loadStartTime was stored as
  as date string format "dd-MM-yyyy HH:mm:ss:SSS". The date string value is specific
  to the timezone. SO the timestamp in long by the date string will not result into
  same value if converted to date in different timezone.
  Json Object of LoadMetaData before CarbonData 1.3
 |-------------------------------------------------------------------------------------------|
 | [{"timestamp":"15-12-2017 16:50:31:703","loadStatus":"Success","loadName":"0",            |
 | "partitionCount":"0","isDeleted":"FALSE","dataSize":"912","indexSize":"700",              |
 | "updateDeltaEndTimestamp":"","updateDeltaStartTimestamp":"","updateStatusFileName":"",    |
 | "loadStartTime":"15-12-2017 16:50:27:493","visibility":"true","fileFormat":"COLUMNAR_V3"}]|
 |-------------------------------------------------------------------------------------------|
  Fix: As the System.currentTimeMillis() returns the same value irrespective of timezone.
  So if Carbon stores the long value for @timestamp  and @loadStartTime value then the
  value will be same irrespective of the timezone.
  Json Object of LoadMetaData for CarbonData 1.3
 |-------------------------------------------------------------------------------------------|
 | [{"timestamp":"1513336827593","loadStatus":"Success","loadName":"0",                      |
 | "partitionCount":"0","isDeleted":"FALSE","dataSize":"912","indexSize":"700",              |
 | "updateDeltaEndTimestamp":"","updateDeltaStartTimestamp":"","updateStatusFileName":"",    |
 | "loadStartTime":"1513336827593","visibility":"true","fileFormat":"COLUMNAR_V3"}]          |
 |-------------------------------------------------------------------------------------------|
 */
public class LoadMetadataDetails implements Serializable {

  private static final long serialVersionUID = 1106104914918491724L;

  private static final Logger LOGGER =
      LogServiceFactory.getLogService(LoadMetadataDetails.class.getName());

  // don't remove static as the write will fail.
  private static final SimpleDateFormat parser =
      new SimpleDateFormat(CarbonCommonConstants.CARBON_TIMESTAMP_MILLIS);

  private String timestamp;

  // For backward compatibility, this member is required to read from JSON in the table_status file
  private SegmentStatus loadStatus;

  // name of the segment
  private String loadName;

  private String dataSize;

  private String indexSize;

  // update delta end timestamp
  private String updateDeltaEndTimestamp;

  // update delta start timestamp
  private String updateDeltaStartTimestamp;

  // this will represent the update status file name at that point of time.
  private String updateStatusFileName;

  /**
   * Segment modification or deletion time stamp
   */
  private String modificationOrDeletionTimestamp;

  private String loadStartTime;

  private String mergedLoadName;

  /**
   * visibility is used to determine whether to the load is visible or not.
   * by default it is true
   */
  private String visibility;

  /**
   * To know if the segment is a major compacted segment or not.
   */
  private String majorCompacted;

  /**
   * the file format of this segment, by default it is FileFormat.COLUMNAR_V3
   */
  private String fileFormat;

  /**
   * Segment path if the segment is added externally.
   */
  private String path;

  /**
   * Segment file name where it has the information of partition information.
   */
  private String segmentFile;

  /**
   * extraInfo will contain segment mapping Information for index table
   */
  private String extraInfo;

  public String getDataSize() {
    return dataSize;
  }

  public void setDataSize(String dataSize) {
    this.dataSize = dataSize;
  }

  public String getIndexSize() {
    return indexSize;
  }

  public void setIndexSize(String indexSize) {
    this.indexSize = indexSize;
  }

  public long getLoadEndTime() {
    if (timestamp == null) {
      return CarbonCommonConstants.SEGMENT_LOAD_TIME_DEFAULT;
    }
    return convertTimeStampToLong(timestamp);
  }

  public void setLoadEndTime(long timestamp) {
    this.timestamp = Long.toString(timestamp);
  }

  public SegmentStatus getSegmentStatus() {
    return loadStatus;
  }

  public void setSegmentStatus(SegmentStatus segmentStatus) {
    this.loadStatus = segmentStatus;
  }

  public String getLoadName() {
    return loadName;
  }

  public void setLoadName(String loadName) {
    this.loadName = loadName;
  }

  /**
   * @return the modificationOrDeletionTimesStamp
   */
  public long getModificationOrDeletionTimestamp() {
    if (null == modificationOrDeletionTimestamp) {
      return 0;
    }
    return convertTimeStampToLong(modificationOrDeletionTimestamp);
  }

  /**
   * @param modificationOrDeletionTimestamp the modificationOrDeletionTimesStamp to set
   */
  public void setModificationOrDeletionTimestamp(long modificationOrDeletionTimestamp) {
    this.modificationOrDeletionTimestamp =
        Long.toString(modificationOrDeletionTimestamp);
  }

  /* (non-Javadoc)
   * @see java.lang.Object#hashCode()
   */
  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((loadName == null) ? 0 : loadName.hashCode());
    return result;
  }

  /* (non-Javadoc)
   * @see java.lang.Object#equals(java.lang.Object)
   */
  @Override
  public boolean equals(Object obj) {
    if (obj == null) {
      return false;

    }
    if (!(obj instanceof LoadMetadataDetails)) {
      return false;
    }
    LoadMetadataDetails other = (LoadMetadataDetails) obj;
    if (loadName == null) {
      if (other.loadName != null) {
        return false;
      }
    } else if (!loadName.equals(other.loadName)) {
      return false;
    }
    return true;
  }

  /**
   * @return the startLoadTime
   */
  public long getLoadStartTime() {
    if (loadStartTime == null) {
      return CarbonCommonConstants.SEGMENT_LOAD_TIME_DEFAULT;
    }
    return convertTimeStampToLong(loadStartTime);
  }

  /**
   * return loadStartTime
   *
   * @return
   */
  public long getLoadStartTimeAsLong() {
    if (!loadStartTime.isEmpty()) {
      Long time = getTimeStamp(loadStartTime);
      if (null != time) {
        return time;
      }
    }
    return 0;
  }

  /**
   * This method will convert a given timestamp to long value and then to string back
   *
   * @param factTimeStamp
   * @return Long    TimeStamp value is milliseconds
   */
  private long convertTimeStampToLong(String factTimeStamp) {
    try {
      return Long.parseLong(factTimeStamp);
    } catch (NumberFormatException nf) {
      SimpleDateFormat parser = new SimpleDateFormat(CarbonCommonConstants.CARBON_TIMESTAMP_MILLIS);
      // it is the processing for existing table before carbon 1.3
      Date dateToStr = null;
      try {
        dateToStr = parser.parse(factTimeStamp);
        return dateToStr.getTime();
      } catch (ParseException e) {
        LOGGER.error("Cannot convert" + factTimeStamp + " to Time/Long type value"
            + e.getMessage(), e);
        parser = new SimpleDateFormat(CarbonCommonConstants.CARBON_TIMESTAMP);
        try {
          // if the load is in progress, factTimeStamp will be null, so use current time
          if (null == factTimeStamp) {
            return System.currentTimeMillis();
          }
          dateToStr = parser.parse(factTimeStamp);
          return dateToStr.getTime();
        } catch (ParseException e1) {
          LOGGER.error(
              "Cannot convert" + factTimeStamp + " to Time/Long type value" + e1.getMessage());
          return 0;
        }
      }
    }
  }

  /**
   * returns load start time as long value
   *
   * @param loadStartTime
   * @return Long  TimeStamp value is nanoseconds
   */
  public Long getTimeStamp(String loadStartTime) {
    try {
      return Long.parseLong(loadStartTime) * 1000L;
    } catch (NumberFormatException nf) {
      // it is the processing for existing table before carbon 1.3
      Date dateToStr = null;
      try {
        dateToStr = parser.parse(loadStartTime);
        return dateToStr.getTime() * 1000;
      } catch (ParseException e) {
        LOGGER.error("Cannot convert" + loadStartTime +
            " to Time/Long type value" + e.getMessage(), e);
        return null;
      }
    }
  }

  /**
   * @param loadStartTime
   */
  public void setLoadStartTime(long loadStartTime) {
    this.loadStartTime = Long.toString(loadStartTime);
  }

  /**
   * @return the mergedLoadName
   */
  public String getMergedLoadName() {
    return mergedLoadName;
  }

  /**
   * @param mergedLoadName the mergedLoadName to set
   */
  public void setMergedLoadName(String mergedLoadName) {
    this.mergedLoadName = mergedLoadName;
  }

  /**
   * @return the visibility
   */
  public String getVisibility() {
    if (visibility == null) {
      return "true";
    }
    return visibility;
  }

  /**
   * @param visibility the visibility to set
   */
  public void setVisibility(String visibility) {
    this.visibility = visibility;
  }

  /**
   * Return true if it is a major compacted segment.
   * @return majorCompacted
   */
  public String isMajorCompacted() {
    return majorCompacted;
  }

  /**
   * Set true if it is a major compacted segment.
   *
   * @param majorCompacted
   */
  public void setMajorCompacted(String majorCompacted) {
    this.majorCompacted = majorCompacted;
  }

  /**
   * To get the update delta end timestamp
   *
   * @return updateDeltaEndTimestamp
   */
  public String getUpdateDeltaEndTimestamp() {
    if (updateDeltaEndTimestamp == null) {
      return "";
    }
    return updateDeltaEndTimestamp;
  }

  /**
   * To set the update delta end timestamp
   *
   * @param updateDeltaEndTimestamp
   */
  public void setUpdateDeltaEndTimestamp(String updateDeltaEndTimestamp) {
    this.updateDeltaEndTimestamp = updateDeltaEndTimestamp;
  }

  /**
   * To get the update delta start timestamp
   *
   * @return updateDeltaStartTimestamp
   */
  public String getUpdateDeltaStartTimestamp() {
    if (updateDeltaStartTimestamp == null) {
      return "";
    }
    return updateDeltaStartTimestamp;
  }

  /**
   * To set the update delta start timestamp
   *
   * @param updateDeltaStartTimestamp
   */
  public void setUpdateDeltaStartTimestamp(String updateDeltaStartTimestamp) {
    this.updateDeltaStartTimestamp = updateDeltaStartTimestamp;
  }

  /**
   * To get the updateStatusFileName
   *
   * @return updateStatusFileName
   */
  public String getUpdateStatusFileName() {
    if (updateStatusFileName == null) {
      return "";
    }
    return updateStatusFileName;
  }

  /**
   * To set the updateStatusFileName
   *
   * @param updateStatusFileName
   */
  public void setUpdateStatusFileName(String updateStatusFileName) {
    this.updateStatusFileName = updateStatusFileName;
  }

  public FileFormat getFileFormat() {
    if (fileFormat == null) {
      return FileFormat.COLUMNAR_V3;
    }
    return new FileFormat(fileFormat);
  }

  public void setFileFormat(FileFormat fileFormat) {
    this.fileFormat = fileFormat.toString();
  }

  public String getSegmentFile() {
    return segmentFile;
  }

  public void setSegmentFile(String segmentFile) {
    this.segmentFile = segmentFile;
  }

  @Override
  public String toString() {
    return "LoadMetadataDetails{" + "loadStatus=" + loadStatus + ", loadName='" + loadName + '\''
        + ", loadStartTime='" + loadStartTime + '\'' + ", segmentFile='" + segmentFile + '\'' + '}';
  }

  public String getExtraInfo() {
    return extraInfo;
  }

  public void setExtraInfo(String extraInfo) {
    this.extraInfo = extraInfo;
  }

  public String getPath() {
    return path;
  }

  public void setPath(String path) {
    this.path = path;
  }

  public boolean isCarbonFormat() {
    return getFileFormat().equals(FileFormat.COLUMNAR_V3)
        || getFileFormat().equals(FileFormat.ROW_V1);
  }

  /**
   * Before writing table status file, call this to make the metadata smaller.
   * It checks if fields are default value, then make it null so GSON does not write it
   */
  void removeUnnecessaryField() {
    if (StringUtils.isEmpty(updateDeltaEndTimestamp)) {
      updateDeltaEndTimestamp = null;
    }
    if (StringUtils.isEmpty(updateDeltaStartTimestamp)) {
      updateDeltaStartTimestamp = null;
    }
    if (StringUtils.isEmpty(updateStatusFileName)) {
      updateStatusFileName = null;
    }
    if (StringUtils.isEmpty(visibility) || visibility.equals("true")) {
      visibility = null;
    }
    if (StringUtils.isEmpty(fileFormat) || fileFormat.equals(FileFormat.COLUMNAR_V3.toString())) {
      fileFormat = null;
    }
  }

  public long getLastModifiedTime() {
    if (updateDeltaEndTimestamp != null) {
      return convertTimeStampToLong(updateDeltaEndTimestamp);
    }
    return convertTimeStampToLong(timestamp);
  }
}
