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

import java.io.IOException;
import java.util.Comparator;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.KeeperException;

import org.apache.hadoop.hdfs.protocol.HdfsConstants;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.hadoop.contrib.bkjournal.BKJournalProtos.EditLogLedgerProto;
import com.google.protobuf.TextFormat;
import static com.google.common.base.Charsets.UTF_8;

/**
 * Utility class for storing the metadata associated 
 * with a single edit log segment, stored in a single ledger
 */
public class EditLogLedgerMetadata {
  static final Log LOG = LogFactory.getLog(EditLogLedgerMetadata.class);

  private String zkPath;
  private final int dataLayoutVersion;
  private final long ledgerId;
  private final long firstTxId;
  private long lastTxId;
  private boolean inprogress;
  
  public static final Comparator COMPARATOR 
    = new Comparator<EditLogLedgerMetadata>() {
    public int compare(EditLogLedgerMetadata o1,
        EditLogLedgerMetadata o2) {
      if (o1.firstTxId < o2.firstTxId) {
        return -1;
      } else if (o1.firstTxId == o2.firstTxId) {
        return 0;
      } else {
        return 1;
      }
    }
  };

  EditLogLedgerMetadata(String zkPath, int dataLayoutVersion,
                        long ledgerId, long firstTxId) {
    this.zkPath = zkPath;
    this.dataLayoutVersion = dataLayoutVersion;
    this.ledgerId = ledgerId;
    this.firstTxId = firstTxId;
    this.lastTxId = HdfsConstants.INVALID_TXID;
    this.inprogress = true;
  }
  
  EditLogLedgerMetadata(String zkPath, int dataLayoutVersion,
                        long ledgerId, long firstTxId,
                        long lastTxId) {
    this.zkPath = zkPath;
    this.dataLayoutVersion = dataLayoutVersion;
    this.ledgerId = ledgerId;
    this.firstTxId = firstTxId;
    this.lastTxId = lastTxId;
    this.inprogress = false;
  }

  String getZkPath() {
    return zkPath;
  }

  long getFirstTxId() {
    return firstTxId;
  }
  
  long getLastTxId() {
    return lastTxId;
  }
  
  long getLedgerId() {
    return ledgerId;
  }
  
  boolean isInProgress() {
    return this.inprogress;
  }

  int getDataLayoutVersion() {
    return this.dataLayoutVersion;
  }

  void finalizeLedger(long newLastTxId) {
    assert this.lastTxId == HdfsConstants.INVALID_TXID;
    this.lastTxId = newLastTxId;
    this.inprogress = false;      
  }
  
  static EditLogLedgerMetadata read(ZooKeeper zkc, String path)
      throws IOException, KeeperException.NoNodeException  {
    try {
      byte[] data = zkc.getData(path, false, null);

      EditLogLedgerProto.Builder builder = EditLogLedgerProto.newBuilder();
      if (LOG.isDebugEnabled()) {
        LOG.debug("Reading " + path + " data: " + new String(data, UTF_8));
      }
      TextFormat.merge(new String(data, UTF_8), builder);
      if (!builder.isInitialized()) {
        throw new IOException("Invalid/Incomplete data in znode");
      }
      EditLogLedgerProto ledger = builder.build();

      int dataLayoutVersion = ledger.getDataLayoutVersion();
      long ledgerId = ledger.getLedgerId();
      long firstTxId = ledger.getFirstTxId();
      if (ledger.hasLastTxId()) {
        long lastTxId = ledger.getLastTxId();
        return new EditLogLedgerMetadata(path, dataLayoutVersion,
                                         ledgerId, firstTxId, lastTxId);
      } else {
        return new EditLogLedgerMetadata(path, dataLayoutVersion,
                                         ledgerId, firstTxId);
      }
    } catch(KeeperException.NoNodeException nne) {
      throw nne;
    } catch(KeeperException ke) {
      throw new IOException("Error reading from zookeeper", ke);
    } catch (InterruptedException ie) {
      throw new IOException("Interrupted reading from zookeeper", ie);
    }
  }
    
  void write(ZooKeeper zkc, String path)
      throws IOException, KeeperException.NodeExistsException {
    this.zkPath = path;

    EditLogLedgerProto.Builder builder = EditLogLedgerProto.newBuilder();
    builder.setDataLayoutVersion(dataLayoutVersion)
      .setLedgerId(ledgerId).setFirstTxId(firstTxId);

    if (!inprogress) {
      builder.setLastTxId(lastTxId);
    }
    try {
      zkc.create(path, TextFormat.printToString(builder.build()).getBytes(UTF_8),
                 Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
    } catch (KeeperException.NodeExistsException nee) {
      throw nee;
    } catch (KeeperException e) {
      throw new IOException("Error creating ledger znode", e);
    } catch (InterruptedException ie) {
      throw new IOException("Interrupted creating ledger znode", ie);
    }
  }
  
  boolean verify(ZooKeeper zkc, String path) {
    try {
      EditLogLedgerMetadata other = read(zkc, path);
      if (LOG.isTraceEnabled()) {
        LOG.trace("Verifying " + this.toString() 
                  + " against " + other);
      }
      return other.equals(this);
    } catch (KeeperException e) {
      LOG.error("Couldn't verify data in " + path, e);
      return false;
    } catch (IOException ie) {
      LOG.error("Couldn't verify data in " + path, ie);
      return false;
    }
  }
  
  public boolean equals(Object o) {
    if (!(o instanceof EditLogLedgerMetadata)) {
      return false;
    }
    EditLogLedgerMetadata ol = (EditLogLedgerMetadata)o;
    return ledgerId == ol.ledgerId
      && dataLayoutVersion == ol.dataLayoutVersion
      && firstTxId == ol.firstTxId
      && lastTxId == ol.lastTxId;
  }

  public int hashCode() {
    int hash = 1;
    hash = hash * 31 + (int) ledgerId;
    hash = hash * 31 + (int) firstTxId;
    hash = hash * 31 + (int) lastTxId;
    hash = hash * 31 + (int) dataLayoutVersion;
    return hash;
  }
    
  public String toString() {
    return "[LedgerId:"+ledgerId +
      ", firstTxId:" + firstTxId +
      ", lastTxId:" + lastTxId +
      ", dataLayoutVersion:" + dataLayoutVersion + "]";
  }

}
