#!/bin/bash

: "${USE_AIKAR_FLAGS:=false}"
: "${USE_MEOWICE_FLAGS:=false}"
: "${USE_MEOWICE_GRAALVM_FLAGS:=false}"

if isTrue "${USE_MEOWICE_FLAGS}" || isTrue "${USE_MEOWICE_GRAALVM_FLAGS}"; then
  java_major_version=$(mc-image-helper java-release)
fi

if isTrue "${USE_MEOWICE_FLAGS}"; then
  if [[ $java_major_version -gt 16 ]]; then
    log "Java version $java_major_version using MeowIce's flags for Java 17+"
  else
    log "Your Java version is $java_major_version, MeowIce's flags are for Java 17+ falling back to Aikar's"
    USE_MEOWICE_FLAGS=FALSE
    USE_AIKAR_FLAGS=TRUE
  fi
fi

if isTrue "${USE_AIKAR_FLAGS}" || isTrue "${USE_MEOWICE_FLAGS}"; then
  # From https://mcflags.emc.gs/
  if isTrue "${USE_MEOWICE_FLAGS}"; then
    log "Using MeowIce's flags"
    G1NewSizePercent=28
    G1MaxNewSizePercent=50
    G1HeapRegionSize=16M
    G1ReservePercent=15
    InitiatingHeapOccupancyPercent=20
    G1MixedGCCountTarget=3
    G1RSetUpdatingPauseTimePercent=0
  elif [[ $MAX_MEMORY ]] && (( $(normalizeMemSize "${MAX_MEMORY}") >= $(normalizeMemSize 12g) )); then
    log "Using Aikar's >12GB flags"
    G1NewSizePercent=40
    G1MaxNewSizePercent=50
    G1HeapRegionSize=16M
    G1ReservePercent=15
    InitiatingHeapOccupancyPercent=20
    G1MixedGCCountTarget=4
    G1RSetUpdatingPauseTimePercent=5
  else
    log "Using Aikar's flags"
    G1NewSizePercent=30
    G1MaxNewSizePercent=40
    G1HeapRegionSize=8M
    G1ReservePercent=20
    InitiatingHeapOccupancyPercent=15
    G1MixedGCCountTarget=4
    G1RSetUpdatingPauseTimePercent=5
  fi

  JVM_XX_OPTS="${JVM_XX_OPTS}
  -XX:+UseG1GC
  -XX:+ParallelRefProcEnabled
  -XX:MaxGCPauseMillis=200
  -XX:+UnlockExperimentalVMOptions
  -XX:+DisableExplicitGC
  -XX:+AlwaysPreTouch
  -XX:G1NewSizePercent=${G1NewSizePercent}
  -XX:G1MaxNewSizePercent=${G1MaxNewSizePercent}
  -XX:G1HeapRegionSize=${G1HeapRegionSize}
  -XX:G1ReservePercent=${G1ReservePercent}
  -XX:G1HeapWastePercent=5
  -XX:G1MixedGCCountTarget=${G1MixedGCCountTarget}
  -XX:InitiatingHeapOccupancyPercent=${InitiatingHeapOccupancyPercent}
  -XX:G1MixedGCLiveThresholdPercent=90
  -XX:G1RSetUpdatingPauseTimePercent=${G1RSetUpdatingPauseTimePercent}
  -XX:SurvivorRatio=32
  -XX:+PerfDisableSharedMem
  -XX:MaxTenuringThreshold=1
  "
  if isTrue "${USE_AIKAR_FLAGS}"; then
    JVM_XX_OPTS="${JVM_XX_OPTS}
    -Dusing.aikars.flags=https://mcflags.emc.gs
    -Daikars.new.flags=true
    "
  fi
fi

if isTrue "${USE_MEOWICE_FLAGS}"; then
  JVM_XX_OPTS="${JVM_XX_OPTS}
  -XX:+UnlockDiagnosticVMOptions
  -XX:+UnlockExperimentalVMOptions
  -XX:G1SATBBufferEnqueueingThresholdPercent=30
  -XX:G1ConcMarkStepDurationMillis=5
  -XX:+UseNUMA
  -XX:-DontCompileHugeMethods
  -XX:MaxNodeLimit=240000
  -XX:NodeLimitFudgeFactor=8000
  -XX:ReservedCodeCacheSize=400M
  -XX:NonNMethodCodeHeapSize=12M
  -XX:ProfiledCodeHeapSize=194M
  -XX:NonProfiledCodeHeapSize=194M
  -XX:NmethodSweepActivity=1
  -XX:+UseFastUnorderedTimeStamps
  -XX:+UseCriticalJavaThreadPriority
  -XX:AllocatePrefetchStyle=3
  -XX:+AlwaysActAsServerClassMachine
  -XX:+UseTransparentHugePages
  -XX:LargePageSizeInBytes=2M
  -XX:+UseLargePages
  -XX:+EagerJVMCI
  -XX:+UseStringDeduplication
  -XX:+UseAES
  -XX:+UseAESIntrinsics
  -XX:+UseFMA
  -XX:+UseLoopPredicate
  -XX:+RangeCheckElimination
  -XX:+OptimizeStringConcat
  -XX:+UseCompressedOops
  -XX:+UseThreadPriorities
  -XX:+OmitStackTraceInFastThrow
  -XX:+RewriteBytecodes
  -XX:+RewriteFrequentPairs
  -XX:+UseFPUForSpilling
  -XX:+UseVectorCmov
  -XX:+UseXMMForArrayCopy
  -XX:+EliminateLocks
  -XX:+DoEscapeAnalysis
  -XX:+AlignVector
  -XX:+OptimizeFill
  -XX:+EnableVectorSupport
  -XX:+UseCharacterCompareIntrinsics
  -XX:+UseCopySignIntrinsic
  -XX:+UseVectorStubs
  "
  if [[ $(arch) == "x86_64" ]]; then
    JVM_XX_OPTS="${JVM_XX_OPTS}
    -XX:+UseFastStosb
    -XX:+UseNewLongLShift
    -XX:+UseXmmI2D
    -XX:+UseXmmI2F
    -XX:+UseXmmLoadAndClearUpper
    -XX:+UseXmmRegToRegMoveAll
    -XX:UseAVX=2
    -XX:UseSSE=4
    "
  else
    log "cpu not x86_64, disabling architecture specific flags"
  fi
  if [[ $java_major_version -gt 23 ]]; then
    JVM_XX_OPTS="${JVM_XX_OPTS}
    -XX:+UseCompactObjectHeaders
    "
  fi
fi

if isTrue "${USE_MEOWICE_GRAALVM_FLAGS}"; then
  if [[ $java_major_version -gt 23 ]]; then
    log "Java 24 or higher detected, using modified GraalVM flags"
    JVM_XX_OPTS="${JVM_XX_OPTS}
    -XX:+UseFastJNIAccessors
    -XX:+UseInlineCaches
    -XX:+SegmentedCodeCache
    -Djdk.nio.maxCachedBufferSize=262144
    -Djdk.graal.UsePriorityInlining=true
    -Djdk.graal.Vectorization=true
    -Djdk.graal.OptDuplication=true
    -Djdk.graal.DetectInvertedLoopsAsCounted=true
    -Djdk.graal.LoopInversion=true
    -Djdk.graal.VectorizeHashes=true
    -Djdk.graal.EnterprisePartialUnroll=true
    -Djdk.graal.VectorizeSIMD=true
    -Djdk.graal.StripMineNonCountedLoops=true
    -Djdk.graal.SpeculativeGuardMovement=true
    -Djdk.graal.TuneInlinerExploration=1
    -Djdk.graal.LoopRotation=true
    -Djdk.graal.CompilerConfiguration=enterprise
    "
  else
    log "Using MeowIce's flags for Graalvm"
    JVM_XX_OPTS="${JVM_XX_OPTS}
    -XX:+UseFastJNIAccessors
    -XX:+UseInlineCaches
    -XX:+SegmentedCodeCache
    -Djdk.nio.maxCachedBufferSize=262144
    -Dgraal.UsePriorityInlining=true
    -Dgraal.Vectorization=true
    -Dgraal.OptDuplication=true
    -Dgraal.DetectInvertedLoopsAsCounted=true
    -Dgraal.LoopInversion=true
    -Dgraal.VectorizeHashes=true
    -Dgraal.EnterprisePartialUnroll=true
    -Dgraal.VectorizeSIMD=true
    -Dgraal.StripMineNonCountedLoops=true
    -Dgraal.SpeculativeGuardMovement=true
    -Dgraal.TuneInlinerExploration=1
    -Dgraal.LoopRotation=true
    -Dgraal.OptWriteMotion=true
    -Dgraal.CompilerConfiguration=enterprise
    "
  fi
fi

if isTrue "${USE_FLARE_FLAGS}"; then
  JVM_XX_OPTS="${JVM_XX_OPTS}
  -XX:+UnlockDiagnosticVMOptions
  -XX:+DebugNonSafepoints
  "
fi

if isTrue "${USE_SIMD_FLAGS}"; then
  JVM_XX_OPTS="${JVM_XX_OPTS}
  --add-modules=jdk.incubator.vector
  "
fi
