package com.rti.dds.snippets;

import java.util.ArrayList;
import java.util.Arrays;

import com.rti.dds.cdr.CdrInputStream;
import com.rti.dds.cdr.CdrOutputStream;
import com.rti.dds.typecode.TypeCode;
import com.rti.dds.typecode.TypeCodeFactory;
import com.rti.dds.util.NativeInterface;

/**
 * This class contains utility functions that illustrate how to serialize a TypeCode into
 * a byte representation and how to reconstruct a TypeCode by deserializing its byte representation
 *
 */
public class TypeCodeSerialization {
    
    /** This function illustrates how to serialize a TypeCode in Java such that it can be saved in 
     * a file or sent out-of band.
     *
     * @param typeCode a TypeCode such as the one received via discovery in 
     * the BuitinPublicationTopicData or BuitinSubscriptionTopicData
     * 
     * @return A byte array containing a serialized raw-byte representation of the TypeCode
     */
    public static byte[] serializeTypeCode(TypeCode typeCode) {
        int bufferSize = typeCode.get_serialized_size(0);
        CdrOutputStream stream = new CdrOutputStream(bufferSize);
        typeCode.serialize(stream);
        return stream.getBuffer().getBuffer();
    }
    
    /**
     *  This function illustrates how to create a TypeCode in Java from the serialized representation
     *  obtained by the call to serializeTypeCode(). 
     *  
     * @param serializedTypeCode an array of bytes containing the serialized representation of
     *        a TypeCode such as the one returned by serializeTypeCode()
     *        
     * @return A TypeCode that corresponds to that serialized representation
     */
    public static TypeCode deserializeTypeCode(byte[] serializedTypeCode) {
        boolean needByteSwap =
                NativeInterface.getInstance().isNativeByteOrderLittleEndian();

        CdrInputStream stream = new CdrInputStream(serializedTypeCode, needByteSwap);           
        TypeCode typeCode = 
                TypeCodeFactory.get_instance().create_tc_from_stream(stream);
        
        return typeCode;
    }

    
    public static void main(String args[]) throws InterruptedException {
        
        String NDDSHOME = System.getenv("NDDSHOME");  
        String DYLD_LIBRARY_PATH = System.getenv("DYLD_LIBRARY_PATH");  
        System.out.println("NDDSHOME="+ NDDSHOME);  
        System.out.println("DYLD_LIBRARY_PATH="+ DYLD_LIBRARY_PATH);  
        int domainId = 0;
        
        MonitorDicoveredTypes typesSpy = new MonitorDicoveredTypes();
        if ( !typesSpy.start(domainId) ) {
            return;
        }
        
        ArrayList<TypeCode> discoveredTypes;
        while (true) {
            typesSpy.waitForDiscoveryData();
            discoveredTypes = typesSpy.processDiscoveredTypes();
            
            // Show the serialized representation of the TypeCode and then
            // How to reconstruct a TypeCode
            for (int i=0; i< discoveredTypes.size(); ++i ) {
                byte[] serializedTypeCode = serializeTypeCode(discoveredTypes.get(i));
                
                System.out.println("New Type Discovered:");
                discoveredTypes.get(i).print_IDL(0);
                System.out.println("Serialized representation is:");
                System.out.println(Arrays.toString(serializedTypeCode));
                
                TypeCode recontructedTypecode = deserializeTypeCode(serializedTypeCode);
                System.out.println("Type code resonsructed from serialize representation is:");
                recontructedTypecode.print_IDL(0);
            }
        }
    }

}
