/*
 * Copyright (c) 2002, Iowa State University
 * 
 * This file is part of the StickSync project and is licensed
 * under the BSD license.
 * 
 * $Id: TestLocation.java,v 1.6 2003/10/24 01:36:37 leavens Exp $
 */
package sticksync;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Date;

import junit.framework.TestCase;

/**
 * This is a JUnit test case for the Location class.
 * @author Curtis Clifton
 * @author Gary T. Leavens
 * @version $Revision: 1.6 $
 */
public class TestLocation extends TestCase {

    private File[] testFiles;
    private Location[] testLocs;

    public TestLocation(String name) {
        super(name);    
    }

    /** Run the tests. */
    public static void main(String[] args) {
       junit.textui.TestRunner.run(suite());
    }

    /** Returns the test suite for this test class. */
    public static junit.framework.Test suite() {
        return new junit.framework.TestSuite(TestLocation.class);
    }

    /* -------------------------------------------------------------------------
     * TESTS
     * -------------------------------------------------------------------------*/

    public void testConstructors() {
        for (int i=0; i < testFiles.length; i++) {
            Location l1 = new Location(testFiles[i].getPath());
            assertEquals(l1.getPath(),testLocs[i].getPath());
        }
    }
    
    public void testReadable() {
        for (int i=0; i < testLocs.length; i++) {
            assertTrue(testLocs[i].readable());
        }
    }

    public void testWriteable() {
        for (int i=0; i < testLocs.length; i++) {
            assertTrue(testLocs[i].writeable());
            testFiles[i].setReadOnly();
            assertTrue(!testLocs[i].writeable());
        }
    }

    public void testCopyTo() throws IOException {
        String orig0 = testLocs[0].contentsAsString();
        String orig1 = testLocs[1].contentsAsString();
        assertTrue(!orig0.equals(orig1));
        Date d = testLocs[0].copyTo(testLocs[1]);
        assertEquals(orig0, testLocs[1].contentsAsString());
        assertEquals(d,testLocs[0].modTime());
        assertEquals(d,testLocs[1].modTime());
    }

    public void testAbsorbChangesFrom() throws IOException {
        // !E2! This test assumes merge will fail
        boolean result = testLocs[0].absorbChangesFrom(testLocs[1]);
        assertTrue(!result);
        assertEquals(testLocs[1].contentsAsString(),
                     testLocs[0].getNearbyLocation().contentsAsString());
    }

    /* -------------------------------------------------------------------------
     * TEST FIXTURE SETUP/TEARDOWN
     * -------------------------------------------------------------------------*/

    protected void setUp() throws Exception {
        testFiles = configureTestFiles(2);
        testLocs = new Location[testFiles.length];
        for (int i=0; i<testLocs.length; i++) {
            testLocs[i] = new Location(testFiles[i]);
        }
    }

    protected void tearDown() throws Exception {
        removeTestFiles();
    }

    /* -------------------------------------------------------------------------
     * STATIC HELPER METHODS     * -----------------------------------------------------------------------*/

    /**
     * Creates the given number of test files, named fileI.txt, where 0 &lt;= I
     * and I &lt; count, in the directory returned by getWorkingDirectory().
     * @see #getWorkingDirectory()
     * @return An array of newly instantiated Location objects representing
     *          the newly created files.
     */
    static File[] configureTestFiles(int count) throws IOException {
        File work = getWorkingDirectory();
        work.mkdir();
        File[] result = new File[count];
        for (int i=0; i < result.length; i++) {
            File f = new File(work,"file"+i+".txt");
            Writer wr = null;
            try {
                wr = new BufferedWriter(new FileWriter(f));
                wr.write("Contents of file"+i);
            } catch (IOException e) {
                if (wr != null) {
                    wr.close();
                }
            }
            result[i] = f;
        }
        return result;
    }

    /**
     * Removes the directory returned by getWorkingDirectory(), along with any 
     * files contained therein.
     * @see #getWorkingDirectory()     * @throws IOException     */
    static void removeTestFiles() throws IOException {
        File work = getWorkingDirectory();
        File[] files = work.listFiles();
        for (int i=0; i < files.length; i++) {
            if (!files[i].delete()) {
                throw new IOException("Unable to delete " + files[i]);
            }
        }
        if (!work.delete()) {
            throw new IOException("Unable to delete " + work);
        }
    }

    private static File getWorkingDirectory() {
        File temp = new File(java.lang.System.getProperty("java.io.tmpdir"));
        return new File(temp,"TestStickSync");
    }
}
