/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.jci.monitor;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;

import junit.framework.TestCase;

import org.apache.commons.io.FileUtils;
import org.apache.commons.jci.listeners.AbstractFilesystemAlterationListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * 
 * @author tcurdt
 */
public final class FilesystemAlterationMonitorTestCase extends TestCase {

    private final Log log = LogFactory.getLog(FilesystemAlterationMonitorTestCase.class);

    private FilesystemAlterationMonitor fam;
    private MyFilesystemAlterationListener listener;

    private File directory;

    
    protected void setUp() throws Exception {
        directory = createTempDirectory();
        assertTrue(directory.exists());
        assertTrue(directory.isDirectory());
    }
    
    protected void tearDown() throws Exception {
        FileUtils.deleteDirectory(directory);
    }
    
    
    protected File createDirectory( final String pName ) throws Exception {
        final File newDirectory = new File(directory, pName);
        assertTrue(newDirectory.mkdir());
        assertTrue(newDirectory.exists());
        assertTrue(newDirectory.isDirectory());
        return newDirectory;
    }
    
    protected File writeFile( final String pName, final byte[] pData ) throws Exception {
        final File file = new File(directory, pName);
        final File parent = file.getParentFile();
        if (!parent.exists()) {
            if (!parent.mkdirs()) {
                throw new IOException("could not create" + parent);
            }
        }
        
        log.debug("writing file " + pName + " (" + pData.length + " bytes)");
        
        final FileOutputStream os = new FileOutputStream(file);
        os.write(pData);
        os.close();
        
        assertTrue(file.exists());
        assertTrue(file.isFile());
        
        return file;
    }

    protected File writeFile( final String pName, final String pText ) throws Exception {
        final File file = new File(directory, pName);
        final File parent = file.getParentFile();
        if (!parent.exists()) {
            if (!parent.mkdirs()) {
                throw new IOException("could not create" + parent);
            }
        }
        log.debug("writing " + file);
        final FileWriter writer = new FileWriter(file);
        writer.write(pText);
        writer.close();
        
        assertTrue(file.exists());
        assertTrue(file.isFile());
        
        return file;
    }

    protected File createTempDirectory() throws IOException {
        final File tempFile = File.createTempFile("jci", null);
        
        if (!tempFile.delete()) {
            throw new IOException();
        }
        
        if (!tempFile.mkdir()) {
            throw new IOException();
        }
        
        return tempFile;         
    }


    protected void delay() {
        try {
            Thread.sleep(1500);
        } catch (final InterruptedException e) {
        }
    }


    
    private static class MyFilesystemAlterationListener extends AbstractFilesystemAlterationListener {
    }

    private void start() throws Exception {
        fam = new FilesystemAlterationMonitor();
        listener = new MyFilesystemAlterationListener();
        fam.addListener(directory, listener);
        fam.start();
        listener.waitForFirstCheck();
    }
    
    private void stop() {
        fam.stop();
    }
    
    public void testListenerDoublication() throws Exception {
        fam = new FilesystemAlterationMonitor();
        listener = new MyFilesystemAlterationListener();
        
        fam.addListener(directory, listener);
        assertEquals(1, fam.getListenersFor(directory).length);
        
        fam.addListener(directory, listener); 
        assertEquals(1, fam.getListenersFor(directory).length);
        
        fam.removeListener(listener);
        assertEquals(0, fam.getListenersFor(directory).length);
}

    public void testDirectoryDoublication() throws Exception {
        fam = new FilesystemAlterationMonitor();

        fam.addListener(directory, new MyFilesystemAlterationListener()); 
        assertEquals(1, fam.getListenersFor(directory).length);
        
        fam.addListener(directory, new MyFilesystemAlterationListener()); 
        assertEquals(2, fam.getListenersFor(directory).length);
    }

    public void testCreateFileDetection() throws Exception {
        start();
        
        writeFile("file", "file");
        
        listener.waitForCheck();
        
        assertEquals(1, listener.getCreatedFiles().size());
        
        stop();
    }

    public void testTimeout() throws Exception {
    	listener = new MyFilesystemAlterationListener();
    	
    	try {
        	listener.waitForFirstCheck();
        	fail("should be an timeout");
        } catch(Exception e) {
        	assertEquals("timeout", e.getMessage());
        }

        start();

        try {
        	listener.waitForEvent();
        	fail("should be an timeout");
        } catch(Exception e) {
        	assertEquals("timeout", e.getMessage());
        }
        
        stop();

        try {
        	listener.waitForCheck();
        	fail("should be an timeout");
        } catch(Exception e) {
        	assertEquals("timeout", e.getMessage());
        }
    
    }

    public void testCreateDirectoryDetection() throws Exception {
        start();

        createDirectory("dir");
        
        listener.waitForCheck();
        
        assertEquals(1, listener.getCreatedDirectories().size());
        
        stop();
    }

    public void testDeleteFileDetection() throws Exception {
        start();

        final File file = writeFile("file", "file");

        assertTrue("file should exist", file.exists());
        
        listener.waitForCheck();
        
        assertEquals("expecting 1 file created", 1, listener.getCreatedFiles().size());
        assertEquals("expecting 0 directories changed", 0, listener.getChangedDirectories().size());
        
        file.delete();
        assertFalse("file should not exist", file.exists());

        listener.waitForCheck();
        
        assertEquals("expecting 1 file deleted", 1, listener.getDeletedFiles().size());
        
        stop();        
    }
    public void testDeleteDirectoryDetection() throws Exception {
        start();

        final File dir = createDirectory("dir");
        createDirectory("dir/sub");
        final File file = writeFile("dir/sub/file", "file");

        listener.waitForCheck();
        
        assertEquals(2, listener.getCreatedDirectories().size());
        assertEquals(1, listener.getCreatedFiles().size());

        delay();
        
        FileUtils.deleteDirectory(dir);
        assertTrue(!dir.exists());
        assertTrue(!file.exists());

        listener.waitForCheck();
        
        assertEquals(2, listener.getDeletedDirectories().size());
        assertEquals(1, listener.getDeletedFiles().size());

        stop();
    }

    public void testModifyFileDetection() throws Exception {
        start();

        writeFile("file", "file");
        
        listener.waitForCheck();
        
        assertEquals(1, listener.getCreatedFiles().size());

        delay();

        writeFile("file", "changed file");

        listener.waitForCheck();
        
        assertEquals(1, listener.getChangedFiles().size());
        
        stop();
    }

    public void testCreatingLocalDirectoryChangesLastModified() throws Exception {
        final long modified = directory.lastModified();

        delay();
        
        createDirectory("directory");

        delay();
               
        assertTrue(directory.lastModified() != modified);
    }

    public void testCreatingLocalFileChangesLastModified() throws Exception {
        final long modified = directory.lastModified();

        delay();
        
        writeFile("file", "file");

        delay();

        assertTrue(directory.lastModified() != modified);
    }

    public void testCreatingSubDirectoryChangesLastModified() throws Exception {
        createDirectory("dir");

        final long modified = directory.lastModified();

        delay();

        createDirectory("dir/sub");

        assertTrue(directory.lastModified() == modified);
    }

    public void testCreatingFileInSubDirectoryChangesLastModified() throws Exception {
        createDirectory("dir");

        final long modified = directory.lastModified();

        delay();
                
        writeFile("dir/file", "file");

        assertTrue(directory.lastModified() == modified);
    }
    
    public void testInterval() throws Exception {

        final long interval = 1000;

        start();
        fam.setInterval(interval);

        listener.waitForCheck();
        long t1 = System.currentTimeMillis();

        listener.waitForCheck();
        long t2 = System.currentTimeMillis();
        
        long diff = t2-t1;
        
        // interval should be at around the same interval
        assertTrue("the interval was set to " + interval + " but the time difference was " + diff, (diff > (interval-50)) && (diff < (interval+50)));
        
        stop();
    }    
}
