/*
 * Copyright (c) 2006, 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
 */

package devtests.deployment;

import java.io.File;
import java.io.InputStream;
import java.io.PrintStream;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildLogger;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
import org.apache.tools.ant.taskdefs.ExecTask;
import org.apache.tools.ant.types.Commandline;
import org.testng.annotations.Configuration;
import org.testng.annotations.Test;

/**
 * Very simple example implementation of a Java-based test driver for
 * deployment tests.
 *
 * This implementation relies on the ant-based tests and common files and
 * delegates to targets in those ant scripts.  Over time this delegation
 * could be replaced by Java implementations of the equivalent logic.
 *
 * @author: tjquinn
 */
public abstract class DeploymentTest {
    
    /** indicates if the test class has been initialized yet */
    private boolean isInited = false;
    
    /** ant project based on the build.xml in the current directory */
    protected Project project;
    
    /** the build.xml file in the current directory */
    protected File buildFile;
    
    /** Our current message output status. Follows Project.MSG_XXX. */
    private int msgOutputLevel = Project.MSG_INFO;

    /**Saved values of the streams */
    private PrintStream out;
    private PrintStream err;
    private InputStream in;
    
    /**
     * The Ant logger class. There may be only one logger. It will have
     * the right to use the 'out' PrintStream. The class must implements the
     * BuildLogger interface.
     */
    private String loggerClassname = null;

    /** Creates a new instance of DeploymentTest */
    public DeploymentTest() {
        init();
    }
    
    /**
     *Reports if the class has been initialized or not.
     *@return whether the initialized has occurred or not
     */
    protected boolean isInited() {
        return isInited;
    }
    
    /**
     *Prepare the callable ant environment for the test.
     */
    private void init() {
        if (! isInited()) {

            err = System.err;
            out = System.out;
            in = System.in;
            
            /*
             *Use the build.xml in the current directory.
             */
            buildFile = new File("build.xml");
            
            /*
             *To call into ant, create a new Project and prepare it for use.
             */
            project = new Project();
//            msgOutputLevel = Project.MSG_VERBOSE;
            project.addBuildListener(createLogger());
            project.setBasedir(".");
            
            project.init();
            
            /*
             *Set up the project to use the build.xml in the current directory.
             */
            ProjectHelper helper = ProjectHelper.getProjectHelper();
            helper.parse(project, buildFile);
            
            isInited = true;
        }
    }
    
    /**
     *Assembles the required jar, war, ear files, etc.
     */
    protected void assemble() throws BuildException {
        project.executeTarget("assemble");
    }

    /**
     *Deploys the application using asadmin.
     */
    protected void deploy() {
        project.executeTarget("deploy.asadmin");
    }
    
    /**
     *Redeploys the application using asadmin.
     *Removes app refs first, then deploys, then creates app refs.
     */
    protected void redeploy() {
        project.executeTarget("redeploy.asadmin");
    }

    /**
     *Undeploys the app using asadmin.
     */
    protected void undeploy() {
        project.executeTarget("undeploy.asadmin");
    }

    /**
     *Cleans out the build directory.
     */
    protected void clean() {
        project.executeTarget("clean");
    }    

    /**
     *Constructs an ExecTask instance, linked to the current project, for
     *running the client.
     *This implementation prepares the exec task so it will run the appclient
     *script.
     *@return ExecTask initialized for running the appclient script to execute
     *the generated and retrieved app client
     */
    protected ExecTask prepareRunExecTask() {
        /*
         This is the ant excerpt imitated by the exec task built by this method:
         
         <exec executable="${APPCLIENT}" resultproperty="result" failonerror="false" output="${build}/${log.id}.output.log">
                    <arg line="-client ${archivedir}/${testName}Client.jar"/>
                </exec>
        */
        ExecTask exec = new ExecTask();
        exec.setProject(project);
        String appclientValue = project.getProperty("APPCLIENT");
        exec.setExecutable(appclientValue);
        exec.setFailonerror(false);
        exec.setTaskName("runclient");
        return exec;
    }
    
    /**
     *Prepares a command line argument object for use with the appclient
     *exec task that uses the default set of arguments: the default
     *location and name for the retreived app client jar file.
     *@param exec the ExecTask with which the command line should be associated
     *@return the argument, associated with the exec task, and set to invoke the gen'd app client
     */
    protected Commandline.Argument prepareRunCommandlineArg(ExecTask exec) {
        Commandline.Argument arg = exec.createArg();
        String archiveDir = project.getProperty("archivedir");
        String testName = project.getProperty("testName");
        arg.setLine("-client " + archiveDir + "/" + testName + "Client.jar");
        return arg;
    }
    
    /**
     *Default implementation for executing the app client
     */
    protected void runClient() {
        ExecTask exec = prepareRunExecTask();
        prepareRunCommandlineArg(exec);
        exec.execute();
    }
    
    /**
     *Prepares the test environment by cleaning the build directory
     *and assembling the required jar files.
     */
    @Configuration(beforeTestClass=true)
    public void setup() {
        clean();
        assemble();
    }
    
    /**
     *Cleans up after all tests have run.  In this case, undeploys
     *the application.
     */
    @Configuration(afterTestClass=true)
    public void unsetup() {
        undeploy();
    }

    // The following is inspired by the code in ant itself.
    
    /**
     * Creates the default build logger for sending build events to the ant
     * log.
     *
     * @return the logger instance for this build.
     */
    private BuildLogger createLogger() {
        BuildLogger logger = null;
        if (loggerClassname != null) {
            try {
                Class loggerClass = Class.forName(loggerClassname);
                logger = (BuildLogger) (loggerClass.newInstance());
            } catch (ClassCastException e) {
                System.err.println("The specified logger class "
                    + loggerClassname
                    + " does not implement the BuildLogger interface");
                throw new RuntimeException();
            } catch (Exception e) {
                System.err.println("Unable to instantiate specified logger "
                    + "class " + loggerClassname + " : "
                    + e.getClass().getName());
                throw new RuntimeException();
            }
        } else {
            logger = new DefaultLogger();
        }

        logger.setMessageOutputLevel(msgOutputLevel);
        logger.setOutputPrintStream(out);
        logger.setErrorPrintStream(err);

        return logger;
    }
}
