package com.kryptnostic.kodex.v1.serialization.jackson;

import com.fasterxml.jackson.databind.InjectableValues.Std;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.smile.SmileFactory;
import com.fasterxml.jackson.datatype.guava.GuavaModule;
import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
import com.kryptnostic.crypto.padding.ZeroPaddingStrategy;
import com.kryptnostic.crypto.v1.keys.Kodex;
import com.kryptnostic.multivariate.polynomial.BasePolynomialFunction;
import com.kryptnostic.multivariate.polynomial.CompoundPolynomialFunctionGF2;
import com.kryptnostic.multivariate.polynomial.OptimizedPolynomialFunctionGF2;
import com.kryptnostic.multivariate.polynomial.ParameterizedPolynomialFunctionGF2;

public final class KodexObjectMapperFactory {
    private KodexObjectMapperFactory() {};

    public static ObjectMapper getObjectMapper( Kodex<String> kodex ) {
        ObjectMapper mapper = getBaseMapper();
        configureMapperInjectables( mapper, kodex );
        return mapper;
    }

    public static ObjectMapper getObjectMapper() {
        return getObjectMapper( null );
    }

    public static ObjectMapper getSmileMapper() { 
        ObjectMapper mapper = new ObjectMapper( new SmileFactory() );
        configureMapper( mapper );
        configureMapperInjectables( mapper, null );
        return mapper;
    }
    
    private static ObjectMapper getBaseMapper() {
        ObjectMapper mapper = new ObjectMapper();
        configureMapper( mapper );
        return mapper;
    }
    
    private static void configureMapperInjectables( ObjectMapper mapper , Kodex<String> kodex ) {
        Std injectableValues = new Std();
        injectableValues.addValue( Kodex.class, kodex );
        mapper.setInjectableValues( injectableValues );
        mapper.registerModule( new KodexModule( kodex ) );
    }
    private static void configureMapper(ObjectMapper mapper ) {
        mapper.registerModule( new KodexModule() );
        mapper.registerModule( new GuavaModule() );
        mapper.registerModule( new AfterburnerModule() );
        mapper.registerSubtypes(
                CompoundPolynomialFunctionGF2.class,
                OptimizedPolynomialFunctionGF2.class,
                BasePolynomialFunction.class,
                ParameterizedPolynomialFunctionGF2.class,
                ZeroPaddingStrategy.class );
    }
}

@@ -824,38 +824,200 @@
 ate 
-KodexObjectMapperFactory() %7B%7D;
+static ObjectMapper globalMapper = null;%0A%0A    private KodexObjectMapperFactory() %7B%7D;%0A%0A    public static void setGlobalObjectMapper( ObjectMapper mapper ) %7B%0A        globalMapper = mapper;%0A    %7D
 %0A%0A  
@@ -1259,32 +1259,113 @@
 bjectMapper() %7B%0A
+        if ( globalMapper != null ) %7B%0A            return globalMapper;%0A        %7D%0A
         return g
@@ -1444,17 +1444,16 @@
 pper() %7B
- 
 %0A       
@@ -1623,36 +1623,32 @@
 n mapper;%0A    %7D%0A
-    
 %0A    private sta
@@ -1796,20 +1796,16 @@
 ;%0A    %7D%0A
-    
 %0A    pri
@@ -1868,17 +1868,16 @@
 r mapper
- 
 , Kodex%3C
@@ -2110,24 +2110,25 @@
  ) );%0A    %7D%0A
+%0A
     private 
@@ -2155,16 +2155,17 @@
 eMapper(
+ 
 ObjectMa

add option for global object mapper... sorta hacky, but we need it for android