package nxm.sys.test.junit.lib;

import nxm.sys.lib.BaseFile;
import nxm.sys.lib.Midas;
import nxm.sys.lib.Shell;
import nxm.sys.lib.TextFile;
import nxm.sys.test.junit.NMTestCase;

/** This will test the TextFile class.
    Originally created in response to NXM-2843
    @author Elizabeth Ryan
    @since NeXtMidas 3.7.1
*/
public final class TextFileTest extends NMTestCase {

  /** Creates a new instance of the class.
   *  @param methodName The name of the method being called.
   */
  public TextFileTest (String methodName) {
    super(methodName, null);
  }

  /** Creates a new instance of the class.
   *  @param methodName The name of the method being called.
   *  @param midas      The midas context testTo use when running the tests.
   */
  public TextFileTest (String methodName, Midas midas) {
    super(methodName, midas);
  }
  // macro file and help file input strings for testIsIncludeLine()
  private static final String[] macroInput = {"include nxm.sys.test.input_test_convert.txt",
                                              "include \"nxm.sys.test.input_test_convert.txt\""};
  private static final String[] hlpInput = {"~Include nxm.sys.test.text_file.txt",
                                            "~Include \"nxm.sys.test.text_file.txt\""};

  public void testJavaVsMidasKeepCase () {
    String[] testCasingFiles = new String[] {
        "ALL_UPPER_CASE_FN_20230417", "MixedCaseFileName.txt",
        "lowercasefn.tmp"
    };
    Midas midasMacro = new Midas();
    midasMacro.setIfJavaBehavior(false);
    checkCase(testCasingFiles,midasMacro);
    Midas midasJava = new Midas();
    midasMacro.setIfJavaBehavior(true);
    checkCase(testCasingFiles,midasJava);
  }

  private void checkCase (String[] filenames, Midas thismidas) {
    for (String fn : filenames) {
      TextFile tf = new TextFile(thismidas,fn);
      boolean isJavaUsage = thismidas.isJavaBehavior();
      String usage = (isJavaUsage) ? "Java" : "Macro";
      String expected = fn;
      String actual   = tf.getFileName().toString();
      if (!isJavaUsage && fn.toUpperCase().equals(fn)) expected = expected.toLowerCase();
      assertEquals(usage+" usage TextFile name:"+tf.getFileName(),expected,actual);
      tf.close();
    }
  }

  /**
   * Read test file containing various "Include" statements for testing
   * TextFile.isIncludeLine().  If the filename is surrounded by quotes
   * the method fails. NXM-2843
   */
  public void testIsIncludeLine () {
    Midas M = Shell.getMidasContext();
    if (Shell.isGradleBuild()) {
      M.warning("nxm.sys.junit.lib.TextFileTest skipping testIsIncludeLine() because fails in Gradle build");
      return;
    }
    // write macro and help/explain files to ram: for testing
    TextFile outFile = new TextFile(getMidasContext(),"ram:test_textfile_include_macro{FG=mm}");

    boolean opened = outFile.open(BaseFile.OUTPUT);
    if (opened) {  // write input lines
      for (int i = 0; i < macroInput.length; i++) {
        outFile.writeln(macroInput[i]);
      }
    }
    outFile.close();

    TextFile outHlpFile = new TextFile(getMidasContext(),"ram:test_textfile_include{FG=exp}");

    boolean hOpened = outHlpFile.open(BaseFile.OUTPUT);
    if (hOpened) {
      for (int i = 0; i < hlpInput.length; i++) {
        outHlpFile.writeln(hlpInput[i]);
      }
    }
    outHlpFile.close();

    // Test input strings
    String inclLine = "include";
    Boolean readLine = false;
    int count = 0;

    TextFile inFile = new TextFile(getMidasContext(),"ram:test_textfile_include_macro{FG=mm}");
    if (inFile.open()) {
      inFile.setIncludeString(inclLine);
      // read input file line by line testing for "include"
      for (String line : inFile.readAllLines()) {
        if (line.contains("23.2")) count++;
      }
    }
    if (count==2) readLine = true;
    assertTrue("TextFileTest read include files in test_textfile_include macro. ", readLine);

    inFile.close();

    readLine = false;    // reset
    inclLine = "~Include";
    count = 0;
    TextFile inHlpFile = new TextFile(getMidasContext(),"ram:test_textfile_include{FG=exp}");
    if (inHlpFile.open()) {
      inHlpFile.setIncludeString(inclLine);
      // read input file line by line testing for "include"
      for (String line : inHlpFile.readAllLines()) {
        if (line.contains("23.2")) count++;
      }
    }
    if (count==2) readLine = true;
    assertTrue("TextFileTest read include files in test_textfile_include help file. ", readLine);

    inHlpFile.close();
  }
  // TODO method tests need to be written
  public void testReadAllLines () {}     // tested in testIsIncludeLine
  public void testSetIncludeString () {} // tested in testIsIncludeLine
  public void testOpen() {}              // tested in testIsIncludeLine
  public void testWriteln() {}           // tested in testIsIncludeLine
  public void testClose() {}             // tested in testIsIncludeLine
}