/*
 * Copyright (c) 2011, 2012 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.net4j.util;

import java.lang.reflect.Method;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.security.SecureRandom;
import java.util.Enumeration;
import java.util.GregorianCalendar;
import java.util.Random;

/**
 * Generates 16 byte UUID values and can encode them to Strings, decode from Strings respectively.
 *
 * @author Eike Stepper
 * @since 3.2
 */
public final class UUIDGenerator
{
  public static final int NODE_ADDRESS_BYTES = 6;

  public static final UUIDGenerator DEFAULT = new UUIDGenerator();

  public UUIDGenerator(byte[] nodeAddress)
  {
    Random random = new SecureRandom();

    clockSequence = (short)random.nextInt(16384);
    updateClockSequence();

    if (nodeAddress == null)
    {
      try
      {
        nodeAddress = getHardwareAddress();
      }
      catch (Throwable ex)
      {
        //$FALL-THROUGH$
      }

      if (nodeAddress == null || nodeAddress.length != NODE_ADDRESS_BYTES)
      {
        // Generate a 48 bit node identifier;
        // This is an alternative to the IEEE 802 host address, which is not available in Java.
        nodeAddress = new byte[NODE_ADDRESS_BYTES];
        random.nextBytes(nodeAddress);
      }
    }

    setNodeAddress(nodeAddress);
  }

  public UUIDGenerator()
  {
    this(null);
  }

  public synchronized String generate()
  {
    updateCurrentTime();
    encode(uuid, buffer);
    return new String(buffer);
  }

  public synchronized void generate(byte[] uuid)
  {
    updateCurrentTime();

    for (int i = 0; i < 16; i++)
    {
      uuid[i] = this.uuid[i];
    }
  }

  public String encode(byte[] uuid)
  {
    char[] buffer = createBuffer();
    encode(uuid, buffer);
    return new String(buffer);
  }

  public byte[] decode(String string)
  {
    byte[] uuid = createUUID();

    char c1;
    char c2;
    char c3;
    char c4;

    int i1;
    int i2;
    int i3;
    int i4;

    for (int i = 0; i < 5; ++i)
    {
      c1 = string.charAt(4 * i + 1);
      c2 = string.charAt(4 * i + 2);
      c3 = string.charAt(4 * i + 3);
      c4 = string.charAt(4 * i + 4);

      i1 = BASE64_INDEX[c1 - BASE64_INDEX_OFFSET];
      i2 = BASE64_INDEX[c2 - BASE64_INDEX_OFFSET];
      i3 = BASE64_INDEX[c3 - BASE64_INDEX_OFFSET];
      i4 = BASE64_INDEX[c4 - BASE64_INDEX_OFFSET];

      uuid[3 * i] = (byte)(i1 << 2 | i2 >>> 4);
      uuid[3 * i + 1] = (byte)((i2 & 0xF) << 4 | i3 >>> 2);
      uuid[3 * i + 2] = (byte)((i3 & 0x3) << 6 | i4);
    }

    // Handle the last chars at the end.
    //
    c1 = string.charAt(21);
    c2 = string.charAt(22);

    i1 = BASE64_INDEX[c1 - BASE64_INDEX_OFFSET];
    i2 = BASE64_INDEX[c2 - BASE64_INDEX_OFFSET];

    uuid[15] = (byte)(i1 << 2 | i2 >>> 4);

    return uuid;
  }

  private static final char[] BASE64_DIGITS = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
      'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
      'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
      '8', '9', '-', '_' };

  private static final byte[] BASE64_INDEX;

  private static final int BASE64_INDEX_OFFSET;

  /**
   * An adjustment to convert the Java epoch of Jan 1, 1970 00:00:00 to the epoch required by the IETF specification,
   * Oct 15, 1582 00:00:00.
   */
  private static final long EPOCH_ADJUSTMENT = new GregorianCalendar(1970, 0, 1, 0, 0, 0).getTime().getTime()
      - new GregorianCalendar(1582, 9, 15, 0, 0, 0).getTime().getTime();

  private long lastTime = System.currentTimeMillis() + EPOCH_ADJUSTMENT;

  private short clockSequence;

  private short timeAdjustment;

  private int sleepTime = 1;

  private final char[] buffer = createBuffer();

  /**
   * A cached array of bytes representing the UUID. The second 8 bytes will be kept the same unless the clock sequence
   * has changed.
   */
  private final byte[] uuid = createUUID();

  static
  {
    byte[] index = new byte[256];
    int min = Integer.MAX_VALUE;
    int max = Integer.MIN_VALUE;

    for (byte i = 0; i < BASE64_DIGITS.length; i++)
    {
      char digit = BASE64_DIGITS[i];
      if (digit < min)
      {
        min = digit;
      }

      if (digit > max)
      {
        max = digit;
      }

      index[digit] = i;
    }

    int length = max - min + 1;
    BASE64_INDEX = new byte[length];
    BASE64_INDEX_OFFSET = min;
    System.arraycopy(index, BASE64_INDEX_OFFSET, BASE64_INDEX, 0, length);
  }

  private byte[] getHardwareAddress() throws Throwable
  {
    // getHardwareAddress is a JRE 1.6 method and must be called reflectiviely
    Method method = ReflectUtil.getMethod(NetworkInterface.class, "getHardwareAddress");

    Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
    while (networkInterfaces.hasMoreElements())
    {
      NetworkInterface networkInterface = networkInterfaces.nextElement();

      try
      {
        byte[] nodeAddress = (byte[])ReflectUtil.invokeMethod(method, networkInterface);
        if (nodeAddress != null && nodeAddress.length == NODE_ADDRESS_BYTES)
        {
          return nodeAddress;
        }
      }
      catch (Throwable ex)
      {
        //$FALL-THROUGH$
      }
    }

    throw new SocketException("Hardware address could not be determined");
  }

  private void setNodeAddress(byte[] nodeAddress)
  {
    // Set the most significant bit of the first octet to 1 so as to distinguish it from IEEE node addresses
    //
    nodeAddress[0] |= (byte)0x80;

    // The node identifier is already in network byte order,
    // so there is no need to do any byte order reversing.
    //
    for (int i = 0; i < NODE_ADDRESS_BYTES; ++i)
    {
      uuid[i + 10] = nodeAddress[i];
    }
  }

  /**
   * Updates the clock sequence portion of the UUID. The clock sequence portion may seem odd, but in the specification,
   * the high order byte comes before the low order byte. The variant is multiplexed into the high order octet of
   * clockseq_hi.
   */
  private void updateClockSequence()
  {
    // clockseq_hi
    uuid[8] = (byte)(clockSequence >> 8 & 0x3F | 0x80);
    // clockseq_low
    uuid[9] = (byte)(clockSequence & 0xFF);
  }

  /**
   * Updates the UUID with the current time, compensating for the fact that the clock resolution may be less than 100
   * ns. The byte array will have its first eight bytes populated with the time in the correct sequence of bytes, as per
   * the specification.
   */
  private void updateCurrentTime()
  {
    // Get the current time in milliseconds since the epoch
    // and adjust it to match the epoch required by the specification.
    //
    long currentTime = System.currentTimeMillis() + EPOCH_ADJUSTMENT;

    if (lastTime > currentTime)
    {
      // The system clock has been rewound so the clock sequence must be incremented
      // to ensure that a duplicate UUID is not generated.
      //
      ++clockSequence;

      if (16384 == clockSequence)
      {
        clockSequence = 0;
      }

      updateClockSequence();
    }
    else if (lastTime == currentTime)
    {
      // The system time hasn't changed so add some increment of 100s of nanoseconds to guarantee uniqueness.
      //
      ++timeAdjustment;

      if (timeAdjustment > 9999)
      {
        // Wait so that the clock can catch up and the time adjustment won't overflow.
        try
        {
          Thread.sleep(sleepTime);
        }
        catch (InterruptedException exception)
        {
          // We just woke up.
        }

        timeAdjustment = 0;
        currentTime = System.currentTimeMillis() + EPOCH_ADJUSTMENT;

        while (lastTime == currentTime)
        {
          try
          {
            ++sleepTime;
            Thread.sleep(1);
          }
          catch (InterruptedException exception)
          {
            // We just woke up.
          }
          currentTime = System.currentTimeMillis() + EPOCH_ADJUSTMENT;
        }
      }
    }
    else
    {
      timeAdjustment = 0;
    }

    lastTime = currentTime;

    // Since the granularity of time in Java is only milliseconds,
    // add an adjustment so that the time is represented in 100s of nanoseconds.
    // The version number (1) is multiplexed into the most significant hex digit.
    //
    currentTime *= 10000;
    currentTime += timeAdjustment;
    currentTime |= 0x1000000000000000L;

    // Place the time into the byte array in network byte order.
    //
    for (int i = 0; i < 4; ++i)
    {
      // time_low
      //
      uuid[i] = (byte)(currentTime >> 8 * (3 - i) & 0xFFL);
    }

    for (int i = 0; i < 2; ++i)
    {
      // time_mid
      //
      uuid[i + 4] = (byte)(currentTime >> 8 * (1 - i) + 32 & 0xFFL);
    }

    for (int i = 0; i < 2; ++i)
    {
      // time_hi
      //
      uuid[i + 6] = (byte)(currentTime >> 8 * (1 - i) + 48 & 0xFFL);
    }
  }

  private void encode(byte[] uuid, char[] buffer)
  {
    for (int i = 0; i < 5; ++i)
    {
      buffer[4 * i + 1] = BASE64_DIGITS[uuid[i * 3] >> 2 & 0x3F];
      buffer[4 * i + 2] = BASE64_DIGITS[uuid[i * 3] << 4 & 0x30 | uuid[i * 3 + 1] >> 4 & 0xF];
      buffer[4 * i + 3] = BASE64_DIGITS[uuid[i * 3 + 1] << 2 & 0x3C | uuid[i * 3 + 2] >> 6 & 0x3];
      buffer[4 * i + 4] = BASE64_DIGITS[uuid[i * 3 + 2] & 0x3F];
    }

    // Handle the last byte at the end.
    //
    buffer[21] = BASE64_DIGITS[uuid[15] >> 2 & 0x3F];
    buffer[22] = BASE64_DIGITS[uuid[15] << 4 & 0x30];
  }

  private byte[] createUUID()
  {
    return new byte[16];
  }

  private char[] createBuffer()
  {
    char[] buffer = new char[23];
    buffer[0] = '_';
    return buffer;
  }
}
