/*
 * 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 (final InterruptedException e) {
                    }

                    if (++i > pSecondsTimeout) {
                        log.error("timeout after " + pSecondsTimeout + "s");
                        return false;
                    }

                } else {
                    pSignal.triggered = false;
                    break;
                }
            }
        }
        return true;
    }

}
