package com.kryptnostic.rhizome.hazelcast.serializers;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectOutput;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.primitives.Ints;
import com.kryptnostic.rhizome.hazelcast.objects.OrderedUUIDSet;
import com.kryptnostic.rhizome.hazelcast.objects.UUIDSet;

public class RhizomeUtils {

    static final Logger logger = LoggerFactory.getLogger( RhizomeUtils.class );

    public static class Serializers {

    }

    public static class Sets {
        public static OrderedUUIDSet newOrderedUUIDSetWithExpectedSize( int expected ) {
            return new OrderedUUIDSet( expectedSize( expected ) );
        }

        public static UUIDSet newUUIDSetWithExpectedSize( int expected ) {
            return new UUIDSet( expectedSize( expected ) );
        }

        public static int expectedSize( int expectedSize ) {
            if ( expectedSize < 0 ) {
                throw new IllegalArgumentException( "expectedSize cannot be negative but was: " + expectedSize );
            }
            if ( expectedSize < 3 ) {
                return expectedSize + 1;
            }
            if ( expectedSize < Ints.MAX_POWER_OF_TWO ) {
                return expectedSize + expectedSize / 3;
            }
            return Integer.MAX_VALUE;
        }
    }

    public static class Streams {

        public static void writeByteArray( ObjectOutput out, byte[] bytes ) throws IOException {
            out.writeInt( bytes.length );
            out.write( bytes, 0, bytes.length );
        }

        public static byte[] readByteArray( ObjectInput in ) throws IOException {
            int size = in.readInt();
            byte[] result = new byte[ size ];
            in.readFully( result );
            return result;
        }

        public static String loadResourceToString( final String path ) {
            String resource = null;
            try ( final InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream( path ) ) {
                resource = IOUtils.toString( stream );
            } catch ( final IOException | NullPointerException e ) {
                logger.error( "Failed to load resource from " + path, e );
                return null;
            }

            return resource;
        }
    }
}

@@ -161,16 +161,89 @@
 tOutput;
+%0Aimport java.util.Collection;%0Aimport java.util.Map;%0Aimport java.util.Set;
 %0A%0Aimport
@@ -332,16 +332,55 @@
 ctory;%0A%0A
+import com.google.common.collect.Maps;%0A
 import c
@@ -413,16 +413,101 @@
 s.Ints;%0A
+import com.hazelcast.nio.ObjectDataInput;%0Aimport com.hazelcast.nio.ObjectDataOutput;%0A
 import c
@@ -1617,32 +1617,32 @@
        %7D%0A    %7D%0A%0A
-
     public stati
@@ -1656,24 +1656,1558 @@
  Streams %7B%0A%0A
+        public static void writeStringStringMap( ObjectDataOutput out, Map%3CString, String%3E object ) throws IOException %7B%0A            int size = object.size();%0A            Set%3CString%3E keys = object.keySet();%0A            Collection%3CString%3E vals = object.values();%0A            RhizomeUtils.Streams.writeStringArray( out, keys.toArray( new String%5B size %5D ) );%0A            RhizomeUtils.Streams.writeStringArray( out, vals.toArray( new String%5B size %5D ) );%0A        %7D%0A%0A        public static Map%3CString, String%3E readStringStringMap( ObjectDataInput in ) throws IOException %7B%0A            String%5B%5D keys = RhizomeUtils.Streams.readStringArray( in );%0A            String%5B%5D vals = RhizomeUtils.Streams.readStringArray( in );%0A            Map%3CString, String%3E map = Maps.newHashMapWithExpectedSize( keys.length );%0A            for ( int i = 0; i %3C keys.length; i++ ) %7B%0A                map.put( keys%5B i %5D, vals%5B i %5D );%0A            %7D%0A            return map;%0A        %7D%0A%0A        public static void writeStringArray( ObjectDataOutput out, String%5B%5D strings ) throws IOException %7B%0A            out.writeInt( strings.length );%0A            for ( String string : strings ) %7B%0A                out.writeUTF( string );%0A            %7D%0A        %7D%0A%0A        public static String%5B%5D readStringArray( ObjectDataInput in ) throws IOException %7B%0A            int size = in.readInt();%0A            String%5B%5D strings = new String%5B size %5D;%0A%0A            for ( int i = 0; i %3C size; i++ ) %7B%0A                strings%5B i %5D = in.readUTF();%0A            %7D%0A            return strings;%0A        %7D%0A%0A
         publ

add stringarray and mapStringString helpers