package io.quarkus.runtime.configuration;

import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
import org.wildfly.common.Assert;

import com.oracle.svm.core.annotate.Alias;
import com.oracle.svm.core.annotate.Delete;
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
import com.oracle.svm.core.annotate.TargetElement;
import com.oracle.svm.core.threadlocal.FastThreadLocalFactory;
import com.oracle.svm.core.threadlocal.FastThreadLocalInt;

/**
 */
final class Substitutions {

    static final FastThreadLocalInt depth = FastThreadLocalFactory.createInt();

    @TargetClass(ConfigExpander.class)
    static final class Target_ConfigExpander {
        @Delete
        @TargetElement(name = "depth")
        static ThreadLocal<int[]> origDepth = null;

        @Substitute
        private static boolean enter() {
            final int val = depth.get();
            if (val == ConfigExpander.MAX_DEPTH) {
                return false;
            } else {
                depth.set(val + 1);
                return true;
            }
        }

        @Substitute
        private static void exit() {
            depth.set(depth.get() - 1);
        }
    }

    @TargetClass(ConfigProviderResolver.class)
    static final class Target_ConfigurationProviderResolver {

        @Alias
        @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset)
        private static volatile ConfigProviderResolver instance;
    }

    @TargetClass(ExpandingConfigSource.class)
    static final class Target_ExpandingConfigSource {
        @Delete
        private static ThreadLocal<Boolean> NO_EXPAND;

        @Substitute
        private static boolean isExpanding() {
            return true;
        }

        @Substitute
        public static boolean setExpanding(boolean newValue) {
            if (!newValue)
                throw Assert.unsupported();
            return true;
        }
    }
}

@@ -106,42 +106,8 @@
 ver;
-%0Aimport org.wildfly.common.Assert;
 %0A%0Aim
@@ -635,16 +635,160 @@
 teInt();
+%0A    // 0 = expand so that the default value is to expand%0A    static final FastThreadLocalInt notExpanding = FastThreadLocalFactory.createInt();
 %0A%0A    @T
@@ -1898,36 +1898,55 @@
          return 
-true
+notExpanding.get() == 0
 ;%0A        %7D%0A%0A   
@@ -2041,22 +2041,13 @@
     
-if (!newValue)
+try %7B
 %0A   
@@ -2063,60 +2063,129 @@
     
-throw Assert.unsupported();%0A            return true;
+return notExpanding.get() == 0;%0A            %7D finally %7B%0A                notExpanding.set(newValue ? 0 : 1);%0A            %7D
 %0A   

Support enabling/disabling expansion at run time