/*
 * The MIT License (MIT)
 *
 * Copyright © 2015 John H. Uckele
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright
 * notice and this permission notice shall be included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package io.vivarium.util;

import java.io.Serializable;

import com.google.common.io.BaseEncoding;
import com.google.common.primitives.Longs;
import com.googlecode.gwtstreamer.client.Streamable;

/**
 * Guava based UUID implementation for compatibility with GWT. This class can be used as a plug in replacement for the
 * standard java.util.UUID, but it's worth noting that GWT does not support SecureRandom, so this UUID implementation
 * does not provide the same guarantee of entropy. It's much preferable to generate UUIDs from the java.util.UUID and
 * convert into this class before sending to GWT if possible.
 *
 * @author John H. Uckele
 */
public class UUID implements Serializable, Streamable
{
    private static final long serialVersionUID = -3581776520796287694L;
    private long _long1;
    private long _long2;

    private UUID()
    {
    }

    public static UUID randomUUID()
    {
        UUID uuid = new UUID();

        // This is compatible with a real UUID, but it is not cryptographically secure.
        uuid._long1 = Rand.getInstance().getRandomLong();
        uuid._long2 = Rand.getInstance().getRandomLong2();

        return uuid;
    }

    @Override
    public String toString()
    {
        StringBuilder sb = new StringBuilder();

        // encode first long
        byte[] bytes1 = Longs.toByteArray(_long1);
        sb.append(BaseEncoding.base16().lowerCase().encode(bytes1, 0, 4)).append('-');
        sb.append(BaseEncoding.base16().lowerCase().encode(bytes1, 4, 2)).append('-');
        sb.append(BaseEncoding.base16().lowerCase().encode(bytes1, 6, 2)).append('-');
        // encode second long
        byte[] bytes2 = Longs.toByteArray(_long2);
        sb.append(BaseEncoding.base16().lowerCase().encode(bytes2, 0, 2)).append('-');
        sb.append(BaseEncoding.base16().lowerCase().encode(bytes2, 2, 6));

        return sb.toString();
    }

    public static UUID fromString(String s)
    {
        UUID vid = new UUID();

        s = s.replaceAll("-", "").toLowerCase();

        // decode first long
        byte[] bytes1 = BaseEncoding.base16().lowerCase().decode(s.substring(0, 16));
        vid._long1 = Longs.fromByteArray(bytes1);

        // decode second long
        byte[] bytes2 = BaseEncoding.base16().lowerCase().decode(s.substring(16, 32));
        vid._long2 = Longs.fromByteArray(bytes2);

        return vid;
    }

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

    @Override
    public boolean equals(Object that)
    {
        return this.toString().equals(String.valueOf(that));
    }
}
@@ -1879,27 +1879,111 @@
 = -3
-581776520796287694L
+965221404087809719L;%0A    private static final BaseEncoding ENCODING = BaseEncoding.base16().lowerCase()
 ;%0A  
@@ -2339,25 +2339,24 @@
 domLong2();%0A
-%0A
         retu
@@ -2571,41 +2571,16 @@
 end(
-BaseEncoding.base16().lowerCase()
+ENCODING
 .enc
@@ -2633,41 +2633,16 @@
 end(
-BaseEncoding.base16().lowerCase()
+ENCODING
 .enc
@@ -2695,41 +2695,16 @@
 end(
-BaseEncoding.base16().lowerCase()
+ENCODING
 .enc
@@ -2838,41 +2838,16 @@
 end(
-BaseEncoding.base16().lowerCase()
+ENCODING
 .enc
@@ -2900,41 +2900,16 @@
 end(
-BaseEncoding.base16().lowerCase()
+ENCODING
 .enc
@@ -3029,17 +3029,18 @@
    UUID 
-v
+uu
 id = new
@@ -3156,41 +3156,16 @@
 1 = 
-BaseEncoding.base16().lowerCase()
+ENCODING
 .dec
@@ -3189,33 +3189,34 @@
 , 16));%0A        
-v
+uu
 id._long1 = Long
@@ -3299,41 +3299,16 @@
 2 = 
-BaseEncoding.base16().lowerCase()
+ENCODING
 .dec
@@ -3341,17 +3341,18 @@
         
-v
+uu
 id._long
@@ -3400,17 +3400,18 @@
  return 
-v
+uu
 id;%0A    

Refactor of UUID code