package nxm.sys.test.junit.lib;

import java.util.Arrays;

import nxm.sys.lib.*;
import nxm.sys.test.junit.NMTestCase;

/** This will test the RamResource class.
    @author  Neon Ngo
    @version $Id: RamResourceTest.java,v 1.2 2012/10/17 16:30:13 ntn Exp $
    @since NeXtMidas 3.1.2
 */
public final class RamResourceTest extends NMTestCase {
  /** public constructor to allow running this test case directly with JUnit. */
  public RamResourceTest (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 testTo use when running the tests.
   */
  public RamResourceTest (String methodName, Midas midas) {
    super(methodName, midas);
    res.setContext(getMidasContext());
    res.setType(IOResource.RAM);
    res.setURL("ram:testramfile");
  }

  private RamResource res = new RamResource();

  @Override
  protected void setUp() throws Exception {
    boolean result = res.open(IOResource.DIR_OUTPUT);
    assertTrue("open resource", result);
    assertTrue("res.isOpen state", res.isOpen);
  }

  @Override
  protected void tearDown() throws Exception {
    boolean result = res.close();
    assertTrue("closed resource", result);
  }

  //////////////////////////////////////////////////////////////////////////////////////////////////
  public void testSetLength () {
    final int newLength = 312;
    res.setLength(newLength);
    assertEquals("set/get Length", newLength, res.getLength());

    // test for setting length to negative value (BUG 2585)
    assertException("set size to negative value", MidasException.class,
      new Runnable() { public void run() { res.setLength(-1); } }
    );

    // test for setting length beyond RamFile's 2 GiB limit (BUG 2585)
    assertException("set size beyond max limit", MidasException.class,
      new Runnable() { public void run() { res.setLength(Integer.MAX_VALUE + 1); } }
    );
  }

  public void testWrite () {
    long origPos = res.seek();
    final int len = 16;
    final byte[] data = new byte[len];
    Arrays.fill(data, (byte)'N');
    res.write(data, 0, len);
    assertEquals("seek position after write", origPos + len, res.seek());

    res.seek(origPos);
    assertEquals("seek position after seek", origPos, res.seek());

    final byte[] readbuf = new byte[len];
    int bytesRead = res.read(readbuf, 0, len);
    assertEquals("seek position after read", origPos + bytesRead, res.seek());
    assertArrayEquals("write/read byte array data", data, readbuf);

    // test writing beyond RamFile's 2 GiB limit (BUG 2585)
    res.seek(RamResource.RamFile.MAX_SIZE);
    assertException("write beyond limit", MidasException.class,
      new Runnable() { public void run() { res.write(data, 0, len); } }
    );

    // test reading beyond RamFile's 2 GiB limit
    res.seek(RamResource.RamFile.MAX_SIZE);
    bytesRead = res.read(readbuf, 0, len);
    assertEquals("read beyond EOF", -1, bytesRead);
  }

  public void testIsFile () {
    assertTrue("isFile", res.isFile());
  }

  public void testDelete () {
    assertTrue("exists", res.exists());

    boolean result = res.delete();
    assertTrue("delete", result);
    assertFalse("exists", res.exists());
  }

  public void testClose     () {} // tested in tearDown()
  public void testExists    () {} // tested in testDelete()
  public void testGetLength () {} // tested in testSetLength()
  public void testOpen      () {} // tested in setUp()
  public void testRead      () {} // tested in testWrite()
  public void testSeek      () {} // tested in testWrite()
  public void testSetURL    () {} // tested in setUp()
}
