/*
 * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

/*
 * TestProgressObjectImpl.java
 *
 * Created on January 15, 2004, 10:10 AM
 */

import javax.enterprise.deploy.spi.status.ProgressListener;
import org.glassfish.deployapi.ProgressObjectImpl;
import org.glassfish.deployapi.TargetImpl;
import org.glassfish.deployment.client.DeploymentFacilityFactory;
import org.glassfish.deployment.client.DeploymentFacility;
import org.glassfish.deployment.client.AbstractDeploymentFacility;
import javax.enterprise.deploy.shared.StateType;

import java.io.File;
import java.io.PrintStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;

/**
 *Makes sure that the ProgressObjectImpl class functions correctly.
 *<p>
 *In particular, bug 4977764 reported that the ProgressObjectImpl class was susceptible to 
 *concurrent update failures in the vector that holds registered progress listeners.  The
 *fireProgressEvent method worked with the vector of listeners itself rather than a clone of the vector.
 *One of the listeners unregistered itself from the progress object, so when the iterator tried to
 *get the next element it detected the concurrent update.   So, the progress object now clones the vector
 *temporarily in fireProgressEvent and iterates through the clone.
 *
 * @author  tjquinn
 */
public class TestProgressObjectImpl {

    private static final String here = "devtests/deployment/jsr88/misc";
    
    /**
     *Provides a concrete implementation of the progress object for testing.  Note that the behavior being
     *tested is actually that of the superclass ProgressObjectImpl.
     */
    public class MyProgressObjectImpl extends ProgressObjectImpl {
       
        public MyProgressObjectImpl(TargetImpl target) {
            super(target);
        }
        
        /**
         *Required by the abstract class definition but not used during testing.
         */
        public void run() {}
        
        /**
         *Stands in as an operation that fires an event to registered listeners.
         */
        public void act() {
            fireProgressEvent(StateType.RUNNING, "starting");
            /*
             *This is where any real work would be done.  It's useful to test with two events just in case
             *that would uncover any problems.
             */
            fireProgressEvent(StateType.COMPLETED, "done");
        }
    }
    
    /**
     *Adds a new listener during the event handling.
     */
    public class MeddlingListenerAdder implements ProgressListener {
        
    
        public void handleProgressEvent(javax.enterprise.deploy.spi.status.ProgressEvent progressEvent) {
            /*
             *Meddle in the listener list by adding a new listener to the list.  This should trigger the error
             *in the original version of ProgressObjectImpl but should not in the fixed version.
             */
            TestProgressObjectImpl.this.theProgressObjectImpl.addProgressListener(new TestProgressObjectImpl.MeddlingListenerRemover());
        }
        
    }
    
    /**
     *Removes itself as a listener during the event handling.
     */
    public class MeddlingListenerRemover implements ProgressListener {
        
    
        public void handleProgressEvent(javax.enterprise.deploy.spi.status.ProgressEvent progressEvent) {
            /*
             *Meddle in the listener list by removing itself from the list.  This should trigger the error
             *in the original version of ProgressObjectImpl but should not in the fixed version.
             */
            TestProgressObjectImpl.this.theProgressObjectImpl.removeProgressListener(this);
        }
        
    }
    
    /* Local progress object implementation to be tested. */
    private MyProgressObjectImpl theProgressObjectImpl;
        
    /** Creates a new instance of TestProgressObjectImpl */
    public TestProgressObjectImpl() {
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        TestProgressObjectImpl test = new TestProgressObjectImpl();
        try {
            test.run(args);
            test.pass();
        } catch (Throwable th) {
            th.printStackTrace(System.out);
            test.fail();
        }
    }
    
    public void run(String[] args) {
        addNewListenerDuringEventHandling();
    }

    /**
     * Tamper with the listener list by adding a new listener during event handling.  
     */
    private void addNewListenerDuringEventHandling() {
        /*
         *Create a TargetImpl just to satisfy the signature of the constructor for the progress object implementation.
         */
        DeploymentFacility df = DeploymentFacilityFactory.getDeploymentFacility();
        TargetImpl target = new TargetImpl((AbstractDeploymentFacility)df, "test", "test");
        theProgressObjectImpl = new MyProgressObjectImpl(target);
        TestProgressObjectImpl.MeddlingListenerAdder meddlingListener1 = new TestProgressObjectImpl.MeddlingListenerAdder();
        TestProgressObjectImpl.MeddlingListenerAdder meddlingListener2 = new TestProgressObjectImpl.MeddlingListenerAdder();
        
        theProgressObjectImpl.addProgressListener(meddlingListener1);
        theProgressObjectImpl.addProgressListener(meddlingListener2);
        
        /*
         *Fire an event that will change the listener set.
         */
        theProgressObjectImpl.act();
        
    }
    
    private void log(String message) {
        System.out.println("[TestProgressObjectImpl]:: " + message);
    }

    private void pass() {
        log("PASSED: " + here);
        System.exit(0);
    }

    private void fail() {
        log("FAILED: " + here);
        System.exit(-1);
    }
}
