package org.picocontainer.defaults;

import org.picocontainer.LifecycleManager;
import org.picocontainer.MutablePicoContainer;
import org.picocontainer.Startable;
import org.picocontainer.PicoContainer;
import org.picocontainer.Disposable;

import java.util.List;
import java.util.Iterator;
import java.util.Collections;
import java.io.Serializable;

/**
 * @author Aslak Helles&oslash;y
 * @version $Revision: 0.0 $
 */
public class DefaultLifecycleManager implements LifecycleManager, Serializable {
    private final MutablePicoContainer pico;

    private boolean started = false;
    private boolean disposed = false;

    public DefaultLifecycleManager(MutablePicoContainer pico) {
        this.pico = pico;
    }

    public void start() {
        if (disposed) throw new IllegalStateException("Already disposed");
        if (started) throw new IllegalStateException("Already started");
        List componentInstances = pico.getComponentInstancesOfType(Startable.class);
        for (Iterator iterator = componentInstances.iterator(); iterator.hasNext();) {
            Startable startable = ((Startable) iterator.next());
            startable.start();
        }
        Iterator it = pico.getChildContainers().iterator();
        while (it.hasNext()) {
            PicoContainer pc = (PicoContainer) it.next();
            pc.getComponentInstances();
            pc.start();
        }
        started = true;
    }

    public void stop() {
        if (disposed) throw new IllegalStateException("Already disposed");
        if (!started) throw new IllegalStateException("Not started");
        Iterator it = pico.getChildContainers().iterator();
        while (it.hasNext()) {
            PicoContainer pc = (PicoContainer) it.next();
            pc.stop();
        }
        List componentInstances = pico.getComponentInstancesOfType(Startable.class);
        Collections.reverse(componentInstances);
        for (Iterator iterator = componentInstances.iterator(); iterator.hasNext();) {
            ((Startable) iterator.next()).stop();
        }
        started = false;
    }

    public void dispose() {
        if (disposed) throw new IllegalStateException("Already disposed");
        Iterator it = pico.getChildContainers().iterator();
        while (it.hasNext()) {
            PicoContainer pc = (PicoContainer) it.next();
            pc.dispose();
        }
        List componentInstances = pico.getComponentInstancesOfType(Disposable.class);
        Collections.reverse(componentInstances);
        for (Iterator iterator = componentInstances.iterator(); iterator.hasNext();) {
            ((Disposable) iterator.next()).dispose();
        }
        if (pico.getParent() instanceof MutablePicoContainer) {
            ((MutablePicoContainer) pico.getParent()).removeChildContainer(pico);
        }
        disposed = true;

    }
}
