/*
 * 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.jci2.listeners;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;

import org.apache.commons.jci2.monitor.FilesystemAlterationListener;
import org.apache.commons.jci2.monitor.FilesystemAlterationObserver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * AbstractFilesystemAlterationListener provides some convenience methods helping to
 * implement a FilesystemAlterationListener.
 * @author tcurdt
 */
public abstract class AbstractFilesystemAlterationListener implements FilesystemAlterationListener {

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

    private final Collection<File> createdFiles = new ArrayList<File>();
    private final Collection<File> changedFiles = new ArrayList<File>();
    private final Collection<File> deletedFiles = new ArrayList<File>();
    private final Collection<File> createdDirectories = new ArrayList<File>();
    private final Collection<File> changedDirectories = new ArrayList<File>();
    private final Collection<File> deletedDirectories = new ArrayList<File>();

    
    private final static class Signal {
        public boolean triggered;
    }

    private final Signal eventSignal = new Signal();
    private final Signal checkSignal = new Signal();
    
    protected FilesystemAlterationObserver observer;

    public void onDirectoryCreate( final File pDir ) {
        createdDirectories.add(pDir);
    }
    public void onDirectoryChange( final File pDir ) {
        changedDirectories.add(pDir);
    }
    public void onDirectoryDelete( final File pDir ) {
        deletedDirectories.add(pDir);
    }

    public void onFileCreate( final File pFile) {
        createdFiles.add(pFile);
    }
    public void onFileChange( final File pFile ) {
        changedFiles.add(pFile);
    }
    public void onFileDelete( final File pFile ) {
        deletedFiles.add(pFile);
    }


    public Collection<File> getChangedDirectories() {
        return changedDirectories;
    }

    public Collection<File> getChangedFiles() {
        return changedFiles;
    }

    public Collection<File> getCreatedDirectories() {
        return createdDirectories;
    }

    public Collection<File> getCreatedFiles() {
        return createdFiles;
    }

    public Collection<File> getDeletedDirectories() {
        return deletedDirectories;
    }

    public Collection<File> getDeletedFiles() {
        return deletedFiles;
    }

    protected void signals() {
        if (createdFiles.size() > 0 || createdDirectories.size() > 0 ||
            changedFiles.size() > 0 || changedDirectories.size() > 0 ||
            deletedFiles.size() > 0 || deletedDirectories.size() > 0) {

            log.debug("event signal");

            synchronized(eventSignal) {
                eventSignal.triggered = true;
                eventSignal.notifyAll();
            }
        }

        log.debug("check signal");

        synchronized(checkSignal) {
            checkSignal.triggered = true;
            checkSignal.notifyAll();
        }
    }

    public void onStart( final FilesystemAlterationObserver pObserver ) {
        observer = pObserver;

        createdFiles.clear();
        changedFiles.clear();
        deletedFiles.clear();
        createdDirectories.clear();
        changedDirectories.clear();
        deletedDirectories.clear();
    }

    public void onStop( final FilesystemAlterationObserver pObserver ) {
        signals();
        observer = null;
    }
        
    public void waitForEvent() throws Exception {
        synchronized(eventSignal) {
            eventSignal.triggered = false;
        }
        log.debug("waiting for change");
        if (!waitForSignal(eventSignal, 10)) {
            throw new Exception("timeout");
        }
    }
    
    /**
     * we don't reset the signal so if there was a check it is
     * already true and exit immediatly otherwise it will behave just
     * like waitForCheck()
     * 
     * @throws Exception in case of a timeout
     */
    public void waitForFirstCheck() throws Exception {
        log.debug("waiting for first check");
        if (!waitForSignal(checkSignal, 10)) {
            throw new Exception("timeout");
        }        
    }

    /**
     * wait for the next filesystem check to happen
     * 
     * @throws Exception in case of a timeout
     */
    public void waitForCheck() throws Exception {
        synchronized(checkSignal) {
            checkSignal.triggered = false;
        }
        log.debug("waiting for check");
        if (!waitForSignal(checkSignal, 10)) {
            throw new Exception("timeout");
        }
    }
    
    private boolean waitForSignal(final Signal pSignal, final int pSecondsTimeout) {
        int i = 0;
        while(true) {
            synchronized(pSignal) {
                if (!pSignal.triggered) {
                    try {
                        pSignal.wait(1000);
                    } catch (InterruptedException e) {
                    }

                    if (++i > pSecondsTimeout) {
                        log.error("timeout after " + pSecondsTimeout + "s");
                        return false;
                    }
                    
                } else {
                    pSignal.triggered = false;
                    break;
                }
            }
        }        
        return true;
    }

}
