import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

import java.util.*;
import java.io.File;
import imageorg.*;
import imageviewer.*;

/**
 * A few example test cases for Images. IMPORTANT - assumes
 * that the "pictures" archive supplied with the assignment is
 * in the user's home directory.
 *
 * @author Mark Hall
 * @version 1.0
 */
public class ImageTests extends TestCase {

  // will hold the concrete student implementation
  protected ImageOrganizer m_imageOrg;
  
  public ImageTests(String name) { super(name); }

  protected void setUp() throws Exception {
    File repositoryHome = new File(System.getProperties().
				   getProperty("user.home")
				   + File.separator
				   + "image_org_home");
    Runtime rt = Runtime.getRuntime();
    if (repositoryHome.exists()) {
      // remove the entire repository on disk
      rt.exec("rm -rf "+repositoryHome.getAbsolutePath()).waitFor();
    }
    // remove all files in home directory (ie. try an get rid of the
    // serialized data structure file if any
    rt.exec("sh ./remove.sh").waitFor();

    m_imageOrg = ImageOrganizer.create();
  }

  protected void tearDown() throws Exception {
    //    m_imageOrg.save();
    m_imageOrg = null;
  }

  private boolean importSingleImage(Folder destination) 
    throws Exception {
    Folder home = m_imageOrg.getHome();
    if (home == null) {
      return false;
    }
    if (destination == null) {
      destination = home;
    }
    
    File imageToImport = new File(System.getProperties().
				  getProperty("user.home")
				  + File.separator
				  + "pictures"
				  + File.separator
				  + "landscape1.jpg"
				  );
    m_imageOrg.importFrom(imageToImport, destination);
    return true;
  }



  // -------- Image tests ----------------------

  public void testGetImageName() throws Exception {
    if (!importSingleImage(null)) {
      fail("Unable to get home folder (testGetImageName).");
    }
    
    Folder home = m_imageOrg.getHome();
    Collection contents = home.getImages();
    assertNotNull("getImages should not return null "
		  +"(testGetImage).", contents);

    assertEquals("Should be just one image (testGetImage).",
		 1, contents.size());
    Iterator i = contents.iterator();
    Image image = (Image)i.next();
    assertNotNull("image should not be null (testGetImage).",
		  image);

    assertEquals("Image name should be landscape1.jpg "
		 + "(testGetImageName).",
		 "landscape1.jpg", image.getName());
  }
  
  public void testCopyImage() throws Exception {
    if (!importSingleImage(null)) {
      fail("Unable to get home folder (testCopyImage).");
    }
    
    Folder home = m_imageOrg.getHome();
    Collection contents = home.getImages();
    assertNotNull("getImages should not return null "
		  +"(testCopyImage).", contents);

    assertEquals("Should be just one image (testCopyImage).",
		 1, contents.size());
    Iterator i = contents.iterator();
    Image image = (Image)i.next();

    assertNotNull("image should not be null (testCopyImage).",
		  image);

    Folder destination = home.createSubFolder("dest");
    
    assertNotNull("createSubFolder should return non-null "
		  +"Folder object.(testCopyImage).", destination);

    // test existance on disk of new subFolder
    File subFolder = new File(System.getProperties().
			      getProperty("user.home")
			      + File.separator
			      + "image_org_home"
			      + File.separator
			      + "dest");
    assertTrue("Destination sub folder does not exist "
	       + "(testCopyImage).", subFolder.exists());

    // test the actual copy
    assertTrue("Copy not successful (testCopyImage).",
	       image.copy(destination));

    // test for existence in the sub folder (both data structure
    // and on disk)
    Collection destCont = destination.getContents();
    assertEquals("Destination Folder should contain one file "
		 + "(testCopyImage).", 1, destCont.size());

    contents = home.getContents();
    assertEquals("Should be two FileElements in home folder "
		 +"(testCopyImage)", 2, contents.size());
    
    File destFile =  new File(System.getProperties().
			      getProperty("user.home")
			      + File.separator
			      + "image_org_home"
			      + File.separator
			      + "dest"
			      + File.separator
			      + "landscape1.jpg");
    assertTrue("Image file should exist in sub folder on "
	       + "disk after copy (testCopyImage).",
	       destFile.exists());

    // test for existence of original image file on
    // disk
    File original = new File(System.getProperties().
			     getProperty("user.home")
			     + File.separator
			     + "image_org_home"
			     + File.separator
			     + "landscape1.jpg"
			     );
    assertTrue("Original image should still exist "
	       +"(testCopyImage).", original.exists());
  }

  public void testCopyImageParentFolderHasValidContents() throws Exception {
    if (!importSingleImage(null)) {
      fail("Unable to get home folder (testCopyImage).");
    }
    
    Folder home = m_imageOrg.getHome();
    Collection contents = home.getImages();
    assertNotNull("getImages should not return null "
		  +"(testCopyImageParentFolderHasValidContents).", contents);

    assertEquals("Should be just one image (testCopyImage).",
		 1, contents.size());
    Iterator i = contents.iterator();
    Image image = (Image)i.next();

    assertNotNull("image should not be null (testCopyImageParentFolderHasValidContents).",
		  image);

    Folder destination = home.createSubFolder("dest");
    
    assertNotNull("createSubFolder should return non-null "
		  +"Folder object.(testCopyImageParentFolderHasValidContents).", destination);

    // test existance on disk of new subFolder
    File subFolder = new File(System.getProperties().
			      getProperty("user.home")
			      + File.separator
			      + "image_org_home"
			      + File.separator
			      + "dest");
    assertTrue("Destination sub folder does not exist "
	       + "(testCopyImageParentFolderHasValidContents).", subFolder.exists());

    // test the actual copy
    assertTrue("Copy not successful (testCopyImage).",
	       image.copy(destination));

    // now test to see that parent folder still has original image
    home =  m_imageOrg.getHome();
    contents = home.getImages();
    assertNotNull("getImages should not return null "
		  +"(testCopyImageParentFolderHasValidContents).", contents);

    assertEquals("Should be just one image (testCopyImage).",
		 1, contents.size());
    i = contents.iterator();
    image = (Image)i.next();

    assertNotNull("image should not be null (testCopyImageParentFolderHasValidContents).",
		  image);
  }

  public void testDeleteImage() throws Exception {
    if (!importSingleImage(null)) {
      fail("Unable to get home folder (testDeleteImage).");
    }
    
    Folder home = m_imageOrg.getHome();
    Collection contents = home.getImages();
    assertNotNull("getImages should not return null "
		  +"(testDeleteImage).", contents);

    assertEquals("Should be just one image (testDeleteImage).",
		 1, contents.size());
    Iterator i = contents.iterator();
    Image image = (Image)i.next();

    assertNotNull("image should not be null (testDeleteImage).",
		  image);

    assertTrue("Problem deleting image (testDeleteImage).",
	       image.delete());

    contents = home.getImages();
    assertEquals("Home should contain no Images (testDeleteImage).",
		 0, contents.size());

    // test for non-existence on disk
    File original = new File(System.getProperties().
			     getProperty("user.home")
			     + File.separator
			     + "image_org_home"
			     + File.separator
			     + "landscape1.jpg"
			     );
    assertTrue("Image should no longer exist after delete"
	       +"(testDeleteImage).", !original.exists());
  }

  public static Test suite() {
    return new TestSuite(ImageTests.class);
  }

  public static void main(String [] args) {
    junit.textui.TestRunner.run(suite());
  }
}
