package nxm.sys.test.junit.lib;


import java.io.Closeable;

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

/** This will test the BaseFile class.

    @author  A. Weisz
 */
public class BaseFileTest extends NMTestCase {

  /** public constructor to allow running this test case directly with JUnit. */
  public BaseFileTest (String methodName) {
    this(methodName, null);
  }

  /** Creates a new instance of the class.
      @param methodName The name of the method being called.
      @param midas      The midas context to use when running the tests.
   */
  public BaseFileTest(String methodName, Midas midas) {
    super(methodName, midas);
  }
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
  private static final String[] test_files = {urlDat+"test1000.prm",
                                              urlDat+"test2000_cf.prm",
                                              urlDat+"test2000_tcprec.prm",
                                              urlDat+"test3000.prm",
                                              urlDat+"test6000.prm",
                                              urlDat+"testxy3000.prm",
                                              urlDat+"testxy6000.prm",
                                              urlDat+"world.prm"};

  private static final String[] test_files_1 = {urlDat+"test1000_eeei.prm",
                                                urlDat+"test3000_eeei.prm"};

  private static final String[] test_files_2 = {urlDat+"test1000_ieee.prm",
                                                urlDat+"test3000_ieee.prm"};

///////////////////////////////////////////////////////////////////////////////
  /** Test the hashCode() method to ensure the Java equals/hashcode contract is satisfied. */
  public void testHashCode () {
    // Test Self Equivalence and Hash Codes
    for (int i = 0; i < test_files.length; i++) {
      BaseFile bf1 = new BaseFile(null, test_files[i]);
      BaseFile bf2 = new BaseFile(null, test_files[i]);
      bf1.open();
      bf2.open();
      boolean areEqual = bf1.equals(bf2);
      int hash1 = bf1.hashCode();
      int hash2 = bf2.hashCode();
      assertTrue("testHashCode: BaseFiles Equal", areEqual);
      assertTrue("testHashCode: BaseFile HashCodes Equal", (hash1 == hash2));
      bf1.close();
      bf2.close();
    }

    // Test Similar Files
    for (int i = 0; i < test_files_1.length; i++) {
      BaseFile bf1 = new BaseFile(null, test_files_1[i]);
      BaseFile bf2 = new BaseFile(null, test_files_2[i]);
      bf1.open();
      bf2.open();
      if (bf1.equals(bf2)) {
        int hash1 = bf1.hashCode();
        int hash2 = bf2.hashCode();
        assertTrue("testHashCode: BaseFile HashCodes Equal", (hash1 == hash2));
      }

      bf1.close();
      bf2.close();
    }

    // Test Different Files
    for (int i = 0; i < (test_files_1.length - 1); i++) {
      BaseFile bf1 = new BaseFile(null, test_files[i]);
      BaseFile bf2 = new BaseFile(null, test_files[i+1]);
      bf1.open();
      bf2.open();
      int hash1 = bf1.hashCode();
      int hash2 = bf2.hashCode();
      if (hash1 != hash2) {
        assertFalse("testHashCode: BaseFile Not Equal", bf1.equals(bf2));
      }

      bf1.close();
      bf2.close();
    }
  }

  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) {
      BaseFile bf = new BaseFile(thismidas,fn);
      boolean isJavaUsage = thismidas.isJavaBehavior();
      String usage = (isJavaUsage) ? "Java" : "Macro";
      String expected = fn;
      String actual   = bf.getFileName().toString();
      if (!isJavaUsage && fn.toUpperCase().equals(fn)) expected = expected.toLowerCase();
      assertEquals(usage+" usage BaseFile name:"+bf.getFileName(),expected,actual);
      bf.close();
    }
  }

  /** test the implementation of java.io.Closeable by BaseFile for Bug 2980.
   *  @since NeXtMidas 3.7.0
   */
  public void testIsCloseable () {
    BaseFile bfile = new BaseFile();
    assertTrue("testCloseable BaseFile is instance of Closeable ", bfile instanceof Closeable);
    bfile.close();
  }
}
