/**
 * 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.hdfs.server.namenode;

import java.io.IOException;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.hdfs.server.common.StorageInfo;
import org.apache.hadoop.hdfs.server.namenode.FSImage;

import com.google.common.collect.ComparisonChain;

/**
 * A unique signature intended to identify checkpoint transactions.
 */
@InterfaceAudience.Private
public class CheckpointSignature extends StorageInfo
    implements Comparable<CheckpointSignature> { 

  private static final String FIELD_SEPARATOR = ":";
  private static final int NUM_FIELDS = 7;
  String blockpoolID = "";
  long mostRecentCheckpointTxId;
  long curSegmentTxId;

  CheckpointSignature(FSImage fsImage) {
    super(fsImage.getStorage());
    blockpoolID = fsImage.getBlockPoolID();
    
    mostRecentCheckpointTxId = fsImage.getStorage().getMostRecentCheckpointTxId();
    curSegmentTxId = fsImage.getEditLog().getCurSegmentTxId();
  }

  CheckpointSignature(String str) {
    String[] fields = str.split(FIELD_SEPARATOR);
    assert fields.length == NUM_FIELDS :
      "Must be " + NUM_FIELDS + " fields in CheckpointSignature";
    int i = 0;
    layoutVersion = Integer.valueOf(fields[i++]);
    namespaceID = Integer.valueOf(fields[i++]);
    cTime = Long.valueOf(fields[i++]);
    mostRecentCheckpointTxId  = Long.valueOf(fields[i++]);
    curSegmentTxId  = Long.valueOf(fields[i++]);
    clusterID = fields[i++];
    blockpoolID = fields[i++];
  }

  public CheckpointSignature(StorageInfo info, String blockpoolID,
      long mostRecentCheckpointTxId, long curSegmentTxId) {
    super(info);
    this.blockpoolID = blockpoolID;
    this.mostRecentCheckpointTxId = mostRecentCheckpointTxId;
    this.curSegmentTxId = curSegmentTxId;
  }

  /**
   * Get the cluster id from CheckpointSignature
   * @return the cluster id
   */
  @Override
  public String getClusterID() {
    return clusterID;
  }

  /**
   * Get the block pool id from CheckpointSignature
   * @return the block pool id
   */
  public String getBlockpoolID() {
    return blockpoolID;
  }

  public long getMostRecentCheckpointTxId() {
    return mostRecentCheckpointTxId;
  }

  public long getCurSegmentTxId() {
    return curSegmentTxId;
  }

  /**
   * Set the block pool id of CheckpointSignature.
   * 
   * @param blockpoolID the new blockpool id
   */
  public void setBlockpoolID(String blockpoolID) {
    this.blockpoolID = blockpoolID;
  }
  
  @Override
  public String toString() {
    return String.valueOf(layoutVersion) + FIELD_SEPARATOR
         + String.valueOf(namespaceID) + FIELD_SEPARATOR
         + String.valueOf(cTime) + FIELD_SEPARATOR
         + String.valueOf(mostRecentCheckpointTxId) + FIELD_SEPARATOR
         + String.valueOf(curSegmentTxId) + FIELD_SEPARATOR
         + clusterID + FIELD_SEPARATOR
         + blockpoolID ;
  }

  boolean storageVersionMatches(StorageInfo si) throws IOException {
    return (layoutVersion == si.layoutVersion) && (cTime == si.cTime);
  }

  boolean isSameCluster(FSImage si) {
    return namespaceID == si.getStorage().namespaceID &&
      clusterID.equals(si.getClusterID()) &&
      blockpoolID.equals(si.getBlockPoolID());
  }

  boolean namespaceIdMatches(FSImage si) {
    return namespaceID == si.getStorage().namespaceID;
  }

  void validateStorageInfo(FSImage si) throws IOException {
    if (!isSameCluster(si)
        || !storageVersionMatches(si.getStorage())) {
      throw new IOException("Inconsistent checkpoint fields.\n"
          + "LV = " + layoutVersion + " namespaceID = " + namespaceID
          + " cTime = " + cTime
          + " ; clusterId = " + clusterID
          + " ; blockpoolId = " + blockpoolID
          + ".\nExpecting respectively: "
          + si.getStorage().layoutVersion + "; " 
          + si.getStorage().namespaceID + "; " + si.getStorage().cTime
          + "; " + si.getClusterID() + "; " 
          + si.getBlockPoolID() + ".");
    }
  }

  //
  // Comparable interface
  //
  @Override
  public int compareTo(CheckpointSignature o) {
    return ComparisonChain.start()
      .compare(layoutVersion, o.layoutVersion)
      .compare(namespaceID, o.namespaceID)
      .compare(cTime, o.cTime)
      .compare(mostRecentCheckpointTxId, o.mostRecentCheckpointTxId)
      .compare(curSegmentTxId, o.curSegmentTxId)
      .compare(clusterID, o.clusterID)
      .compare(blockpoolID, o.blockpoolID)
      .result();
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof CheckpointSignature)) {
      return false;
    }
    return compareTo((CheckpointSignature)o) == 0;
  }

  @Override
  public int hashCode() {
    return layoutVersion ^ namespaceID ^
            (int)(cTime ^ mostRecentCheckpointTxId ^ curSegmentTxId)
            ^ clusterID.hashCode() ^ blockpoolID.hashCode();
  }
}
