package nxm.sys.inc;

import nxm.sys.lib.Shell;
import nxm.sys.lib.StringUtil;

/** Definitions of installation specific constants.

    @author Jeff Schoen
 */
public interface Installation {
  /** Indicates if the current version is a pre-release version. <br>
      <br>
      If this is <code>true</code> then the this represents a pre-release of NeXtMidas that will be
      released as version {@link #NM_VERSION} in the near future. If this is <code>false</code> then
      this represents an official release of NeXtMidas {@link #NM_VERSION}. (Note: This value makes
      no indication as whether or not this version has been modified by a customer, in general all
      customer modifications should be listed in <code>$NMROOT/nxm/sys/updates.txt</code> or
      <code>$NMROOT/updates.txt</code>.)<br>
      <br>
      This value will be set to <code>true</code> for all snapshots and development
      baselines/branches in the NeXtMidas SCM repository.
   */
  boolean NM_PRE_RELEASE = false;

  /** Version number for this release of NeXtMidas. <br>
      <br>
      Value = <code>{@value}</code>
   */
  String NM_VERSION = "4.1.4";

  /** Indicates if native methods are supported. */
  boolean NATIVE = true;

  /** Indicates if the X-Midas interface is included. */
  boolean XMIDASIF = false;

  /** Indicates if the M2k interface is included.
      @deprecated Since NeXtMidas 3.5.3, this was never set/used
   */
  @Deprecated
  boolean M2KIF = false;

  /** Indicates if NeXtMidas should run in "Debug Mode". */
  boolean DEBUG = false;

  /** Indicates if NeXtMidas is using a debugger. */
  boolean DEBUGGER = false;

  /** Indicates if Java's Swing packages should be used for graphics. */
  boolean SWING = true;

  /** Enables or disables special bug fixes. All of these constants should be assumed to be
      deprecated since we will remove them as soon as the special work-around is no longer required.
      <br>
      The naming convention is COMMAND_OR_CLASS_FUNCTION_OR_AREA_BRIEF_DESCRIPTION.
      <br>
      NOTE: This provides a mechanism for baseline developers to:<br>
           1. Provide a way to workaround some COTS or internal Bug, until it is no longer needed or properly fixed.<br>
           2. Provide a way to back-out/revert certain NeXtMidas DR fixes that changes behavior for a stable series or two.
      @since NeXtMidas 2.0.1
   */
  @InternalUseOnly("Since NeXtMidas 2.0.1, this has always been meant for internal use only")
  public static final class ApplyBugFix {
    /** Enable the fix to GCONTROL to have /WTHEME= override /THEME= switch.
        To revert to previous behavior, set the BUGFIX.GCONTROL_WTHEME_OVERRIDES_THEME
        system property to false which will take /THEME= over /WTHEME= switch.
        <pre>
          NeXtMidas Bug ID: 2543 GCONTROL: Ignores /WTHEME= if /THEME= is set
        </pre>
        @since NeXtMidas 3.1.1
     */
    // TODO: remove in 3.7+ beta series?
    @InternalUseOnly("Since NeXtMidas 3.1.1, this has always been meant for internal use only")
    public static final boolean GCONTROL_WTHEME_OVERRIDES_THEME
                   = getStatus("GCONTROL_WTHEME_OVERRIDES_THEME", true);

    /** Disable the fix to KEYWORD to have the FSET function overwrite duplicate
        keys in the MAIN header (for a single equal "=") as well as adding to the EXTENDED header
        (for double equals "=="). <br>
        To revert to previous behavior (appending key/value pairs only into the extended  header),
        set the BUGFIX.KEYWORD_FSET_INTO_EXTENDED_ONLY system property to true.
        -or- use the /EXTONLY switch.
        <pre>
          NeXtMidas Bug ID: 2599 KEYWORD: incorrectly puts keywords in extended header with FSET
        </pre>
        @since NeXtMidas 3.1.2
     */
    // TODO: remove in 3.7+ beta series?
    @InternalUseOnly("Since NeXtMidas 3.1.2, this has always been meant for internal use only")
    public static final boolean KEYWORD_FSET_INTO_EXTENDED_ONLY
                   = getStatus("KEYWORD_FSET_INTO_EXTENDED_ONLY", false);

    /** Disable the fix to Generate that prepends "jnlp." to properties when
        generating a jnlp file.<br>
        To revert to previous behavior, set the
        BUGFIX.GENERATE_JNLP_PREPEND_JNLP_TO_PROPERTIES system property to false.
        <pre>
          NeXtMidas Bug ID: 2799 Changes in JDK 7u45 breaks Webstart properties
        </pre>
        @since NeXtMidas 3.4.2
     */
    @InternalUseOnly("Since NeXtMidas 3.4.2, this has always been meant for internal use only")
    public static final boolean GENERATE_JNLP_PREPEND_JNLP_TO_PROPERTIES
                   = getStatus("GENERATE_JNLP_PREPEND_JNLP_TO_PROPERTIES", true);

    /** Disable the fix to xgeoplot.btest(..) that corrects the logic of bit shifting.<br>
        To revert to previous behavior, set the BUGFIX.XGEOPLOT_USE_ORIGINAL_BTEST system property to true.
        <br>Since 3.4.2, can also set BUGFIX.USE_ORIGINAL_XGEOPLOT_BTEST but that system property will no longer be used in 3.7.0+.
        <pre>
          NeXtMidas Bug ID: 2807 XGEOPLOT: btest method is off by one
        </pre>
        @since NeXtMidas 3.4.4
     */
    @InternalUseOnly("Since NeXtMidas 3.4.4, this has always been meant for internal use only")
    public static final boolean XGEOPLOT_USE_ORIGINAL_BTEST
                   = getStatus("XGEOPLOT_USE_ORIGINAL_BTEST", getStatus("USE_ORIGINAL_XGEOPLOT_BTEST", false));

    /** Disable the fix to XGEOPLOT that merges Pnt properties rather than overriding it.<br>
        To revert to previous behavior, set the
        BUGFIX.XGEOPLOT_T5REC_MSG_MERGE_PROPERTIES system property to false.
        <pre>
          NeXtMidas Bug ID: 2823 PLOT: LayerT5 does not allow control of individual plot color w/out FLAG component
        </pre>
        @since NeXtMidas 3.5.1
     */
    @InternalUseOnly("Since NeXtMidas 3.5.1, this has always been meant for internal use only")
    public static final boolean XGEOPLOT_T5REC_MSG_MERGE_PROPERTIES
                   = getStatus("XGEOPLOT_T5REC_MSG_MERGE_PROPERTIES", true);

    /** Workaround JDK 8.0 to 8u11 javadoc bug where it errors building javadocs for NmClassLoader.java.
        Work-around fix is enabled when Java 8.0 is detected.
        <pre>
          Java Bug ID: JDK-8037484 (fixed in 8u20)
          NeXtMidas Bug ID: 2783
        </pre>
     */
    @InternalUseOnly("Since NeXtMidas 3.5.0?, this has always been meant for internal use only")
    public static final boolean WORKAROUND_JDK8_JAVADOC_ISSUE
                   = getStatus("WORKAROUND_JDK8_JAVADOC_ISSUE",
                       (StringUtil.compareVersions("1.8.0", Shell.getJavaVersion()) == 0)
                       && (Shell.getJavaUpdateVersion() < 20));

    /**
        To allow/disallow space as delimiter in addition to commas in LayerWMS (PLOT). Enabling this will
        prevent usage of a WMS layer name with a space via {LAYERS="..."} or calling the setter on the WMS Layer.
        To revert to previous behavior, set the BUGFIX.PLOT_LAYERWMS_ALLOW_SPACE_AS_DELIMITER system property to true.
       <pre>
         NeXtMidas Bug ID: 2880 LayerWMS should support layers with a space in their name
       </pre>
       @since NeXtMidas 3.5.3
    */
    @InternalUseOnly("Since NeXtMidas 3.5.3, this has always been meant for internal use only")
    public static final boolean PLOT_LAYERWMS_ALLOW_SPACE_AS_DELIMITER
                   = getStatus("PLOT_LAYERWMS_ALLOW_SPACE_AS_DELIMITER", false);

    /** Revert to using the old Shaded 'X' for the PUSHPOP icon
        To revert to previous behavior, set the
        BUGFIX.PANEL_REVERT_TO_SHADEDX_PUSHPOP_ICON system property to true.
        <pre>
         NeXtMidas Bug ID: 2896 PANEL/MWindow: change icon of popout (from current X) to something more meaningful
        </pre>
        @since NeXtMidas 3.5.4
     */
     @InternalUseOnly("Since NeXtMidas 3.5.4, this has always been meant for internal use only")
     public static final boolean PANEL_REVERT_TO_SHADEDX_PUSHPOP_ICON
                = getStatus("PANEL_REVERT_TO_SHADEDX_PUSHPOP_ICON", false);

     /** To revert fix for [BUG 2863 (g847095-1) JarResource.exists() memory leak] by to NOT calling JarFile.close().
      *  This allows using OpenJDK's IcedTea-Web's javaws.itweb to run NeXtMidas via Java Web Start to
      *  temporary address [BUG 2897 Web Start not working with with icedtea-web/OpenJDK], which might be
      *  caching JARURLConnection, JarFiles, etc. This will autodetect when running under IcedTea-Web Java web browser
      *  plugin, to disable workaround when running under IcedTea-Web, set the
      *  BUGFIX.JARRESOURCE_ICEDTEA_WEB_WORKAROUND system property to true.
      *  <pre>
      *    NeXtMidas Bug ID: 2897 (g781534-17) Web Start not working with icedtea-web/OpenJDK
      *  </pre>
      *  @since NeXtMidas 3.5.4
      */
     @InternalUseOnly("Since NeXtMidas 3.5.4, this has always been meant for internal use only")
     public static final boolean JARRESOURCE_ICEDTEA_WEB_WORKAROUND
                    = getStatus("JARRESOURCE_ICEDTEA_WEB_WORKAROUND", isIcedTeaWeb());

     /** This constructor was automatically provided by Java,
      *  but it is unneeded as all the methods are static methods.
      *  @deprecated now that Javadocs are required, it is temporarily
      *              being explicitely provided but deprecated
      */
     @Deprecated
     public ApplyBugFix () {}

     /** @since NeXtMidas 3.5.4 */
     private static boolean isIcedTeaWeb() { // this returns false most normal run scenarios
       String prop = Shell.getProperty("icedtea-web.bin.name"); // this system property is set under IcedTea-Web 1.5.1 and proper other versions too
       boolean retval = (prop != null) && (prop.length() > 0);
       //  System.out.println("===========> DEBUG: isIcedTeaWeb = " + retval + " <========================");
       return retval;
     }

    /**  Here is an example special JVM bug workaround. Work-around fix is enabled for Java versions prior to 7.0.
         <pre>
           Broken in:        Java 7.0
           Fixed in:         Java 8.0
           Java Bug ID:      ?
           NeXtMidas Bug ID: ?
         </pre>
     */
    @InternalUseOnly("Since NeXtMidas x.y.z, this has always been meant for internal use only")
    /* public */ static final boolean EXAMPLECOMMAND_BUG_WORKAROUND_BEFORE_JAVA8
                         = getStatus("EXAMPLECOMMAND_BUG_WORKAROUND_BEFORE_JAVA8", !javaVerGEq("1.8.0"));

    /** Indicates if the current Java version is greater than or equal to the given version.
        @param ver The given version number.
        @return <code>false</code> if the Java VM version is earlier than the given version
                number, <code>true</code> if the Java VM version is later than or equal to
                the given version number.
     */
    private static final boolean javaVerGEq (String ver) {
      return StringUtil.compareVersions(ver, Shell.getJavaVersion()) <= 0;
    }

    /** Gets the status of the bug fix.
        @param name The name of the fix.
        @param def  The default value for the fix.
        @return Indicates if the bug fix should be used.
     */
    private static final boolean getStatus (String name, boolean def) {
      String force = Shell.getProperty("BUGFIX." + name);

      return ((force==null)||force.equalsIgnoreCase("AUTO"))? def: StringUtil.isTrue(force);
    }
  } // end inner class ApplyBugFix
} // end interface Installation
