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

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.oncrpc.XDR;

/**
 * This is a file handle use by the NFS clients.
 * Server returns this handle to the client, which is used by the client
 * on subsequent operations to reference the file.
 */
public class FileHandle {
  private static final Log LOG = LogFactory.getLog(FileHandle.class);
  private static final String HEXES = "0123456789abcdef";
  private static final int HANDLE_LEN = 32;
  private byte[] handle; // Opaque handle
  private long fileId = -1;

  public FileHandle() {
    handle = null;
  }

  /**
   * Handle is a 32 bytes number. For HDFS, the last 8 bytes is fileId.
   */
  public FileHandle(long v) {
    fileId = v;
    handle = new byte[HANDLE_LEN];
    handle[0] = (byte)(v >>> 56);
    handle[1] = (byte)(v >>> 48);
    handle[2] = (byte)(v >>> 40);
    handle[3] = (byte)(v >>> 32);
    handle[4] = (byte)(v >>> 24);
    handle[5] = (byte)(v >>> 16);
    handle[6] = (byte)(v >>>  8);
    handle[7] = (byte)(v >>>  0);
    for (int i = 8; i < HANDLE_LEN; i++) {
      handle[i] = (byte) 0;
    }
  }
  
  public FileHandle(String s) {
    MessageDigest digest;
    try {
      digest = MessageDigest.getInstance("MD5");
      handle = new byte[HANDLE_LEN];
    } catch (NoSuchAlgorithmException e) {
      LOG.warn("MD5 MessageDigest unavailable.");
      handle = null;
      return;
    }

    byte[] in = s.getBytes(StandardCharsets.UTF_8);
    digest.update(in);

    byte[] digestbytes = digest.digest();
    for (int i = 0; i < 16; i++) {
      handle[i] = (byte) 0;
    }

    for (int i = 16; i < 32; i++) {
      handle[i] = digestbytes[i - 16];
    }
  }

  public boolean serialize(XDR out) {
    out.writeInt(handle.length);
    out.writeFixedOpaque(handle);
    return true;
  }

  private long bytesToLong(byte[] data) {
    ByteBuffer buffer = ByteBuffer.allocate(8);
    for (int i = 0; i < 8; i++) {
      buffer.put(data[i]);
    }
    buffer.flip();// need flip
    return buffer.getLong();
  }
  
  public boolean deserialize(XDR xdr) {
    if (!XDR.verifyLength(xdr, 32)) {
      return false;
    }
    int size = xdr.readInt();
    handle = xdr.readFixedOpaque(size);
    fileId = bytesToLong(handle);
    return true;
  }
  
  private static String hex(byte b) {
    StringBuilder strBuilder = new StringBuilder();
    strBuilder.append(HEXES.charAt((b & 0xF0) >> 4)).append(
        HEXES.charAt((b & 0x0F)));
    return strBuilder.toString();
  }
  
  public long getFileId() {    
    return fileId;
  }
  
  public byte[] getContent() {
    return handle.clone();
  }
  
  @Override
  public String toString() {
    StringBuilder s = new StringBuilder();
    for (int i = 0; i < handle.length; i++) {
      s.append(hex(handle[i]));
    }
    return s.toString();
  }
  
  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }

    if (!(o instanceof FileHandle)) {
      return false;
    }

    FileHandle h = (FileHandle) o;
    return Arrays.equals(handle, h.handle);
  }

  @Override
  public int hashCode() {
    return Arrays.hashCode(handle);
  }
}
