/*
 *  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.tools.ant.taskdefs;

import static org.junit.Assert.assertTrue;

import java.io.File;
import java.util.GregorianCalendar;

import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.BuildFileRule;
import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
import org.apache.tools.ant.util.FileUtils;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;

/**
 * Unit test for the &lt;exec&gt; task.
 */
public class ExecTaskTest {

    @Rule
    public BuildFileRule buildRule = new BuildFileRule();

    private static final String BUILD_PATH = "src/etc/testcases/taskdefs/exec/";
    private static final String BUILD_FILE = BUILD_PATH + "exec.xml";
    private static final int TIME_TO_WAIT = 1;
    /** maximum time allowed for the build in milliseconds */
    private static final int MAX_BUILD_TIME = 6000;
    private static final int SECURITY_MARGIN = 4000; // wait 4 second extras
    // the test failed with 100 ms of margin on cvs.apache.org on August 1st, 2003
    // the test randomly failed with 3 s of margin on Windows Jenkins slaves on during July 2014

    /** Utilities used for file operations */
    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();

    private File logFile;
    private MonitoredBuild myBuild = null;
    private volatile boolean buildFinished = false;


    @Before
    public void setUp() {
        buildRule.configureProject(BUILD_FILE);
    }

    @Test
    public void testspawn() throws InterruptedException {
        buildRule.getProject().executeTarget("setUp");
        Assume.assumeNotNull(buildRule.getProject().getProperty("test.can.run"));
        myBuild = new MonitoredBuild(new File(System.getProperty("root"), BUILD_FILE), "spawn");
        logFile = FILE_UTILS.createTempFile("spawn", "log", new File(buildRule.getProject().getProperty("output")),
                false, false);
        // this is guaranteed by FileUtils#createTempFile
        assertTrue("log file not existing", !logFile.exists());
        // make the spawned process run 1 seconds
        myBuild.setTimeToWait(TIME_TO_WAIT);
        myBuild.setLogFile(logFile.getAbsolutePath());
        myBuild.addBuildListener(new MonitoredBuildListener());
        myBuild.start();
        GregorianCalendar startwait = new GregorianCalendar();
        // this loop runs parallel to the build
        while (!buildFinished) {
            Thread.sleep(10);
            GregorianCalendar now = new GregorianCalendar();
            // security
            if (now.getTime().getTime() - startwait.getTime().getTime() > MAX_BUILD_TIME) {
                System.out.println("aborting wait, too long "
                        + (now.getTime().getTime() - startwait.getTime().getTime())
                        + "milliseconds");
                break;
            }
        }
        // now wait until the spawned process is finished
        Thread.sleep((TIME_TO_WAIT) * 1000 + SECURITY_MARGIN);
        // time of the build in milli seconds
        long elapsed = myBuild.getTimeElapsed();
        assertTrue("we waited more than the process lasted",
                TIME_TO_WAIT * 1000 + SECURITY_MARGIN > elapsed);
        logFile = new File(logFile.getAbsolutePath());
        assertTrue("log file found after spawn", logFile.exists());
    }

    @Test
    @Ignore("#50507 - fails at least on Linux")
    /* TODO #50507 - fails at least on Linux */
    public void testOutAndErr() {
        buildRule.getProject().executeTarget("test-out-and-err");
    }

    private static class MonitoredBuild implements Runnable {
        private Thread worker;
        private File myBuildFile = null;
        private String target = null;
        private Project project = null;
        private GregorianCalendar timeStarted = null;
        private GregorianCalendar timeFinished = null;

        public void setLogFile(String logFile) {
            project.setProperty("logFile", logFile);
        }

        public void setTimeToWait(int timeToWait) {
            project.setProperty("timeToWait", Long.toString(timeToWait));
        }

        public void addBuildListener(BuildListener bl) {
            project.addBuildListener(bl);
        }

        public MonitoredBuild(File buildFile, String target) {
            myBuildFile = buildFile;
            this.target = target;
            project = new Project();
            project.init();
            project.setUserProperty("ant.file", myBuildFile.getAbsolutePath());
            ProjectHelper.configureProject(project, myBuildFile);
        }

        /**
         *
         * @return time in millis of the build
         */
        public long getTimeElapsed() {
            return timeFinished.getTime().getTime() - timeStarted.getTime().getTime();
        }

        public void start() {
            worker = new Thread(this, myBuildFile.toString() + "/" + target);
            worker.start();
        }

        public void run() {
            startProject();
        }

        private void startProject() {
            timeStarted = new GregorianCalendar();
            project.executeTarget(target);
            timeFinished = new GregorianCalendar();
        }
    }

    private class MonitoredBuildListener implements BuildListener {
        public void buildStarted(BuildEvent event) {
        }

        public void buildFinished(BuildEvent event) {
        }

        public void targetStarted(BuildEvent event) {
        }

        public void targetFinished(BuildEvent event) {
            if (event.getTarget().getName().equals("spawn")) {
                buildFinished = true;
            }
        }

        public void taskStarted(BuildEvent event) {
        }

        public void taskFinished(BuildEvent event) {
        }

        public void messageLogged(BuildEvent event) {
        }
    }

}
