/*
 * 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.ant.antunit.listener;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

import org.apache.ant.antunit.AssertionFailedException;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.util.FileUtils;

/**
 * This AntUnitListener creates a new buildfile with a target for each
 * failed test target in the AntUnit run. The generated target calls
 * the failed target (with setUp and tearDown if present in the called
 * project). 
 * This is intended for rerunning just failed tests.
 */
public class FailureAntUnitListener extends BaseAntUnitListener {
 
    /** LineSeparator just for beautifying the output. */
    private static final String BR = System.getProperty("line.separator"); 

    /** A sorted list (without duplicates) of failed tests. */
    private static SortedSet failedTests = new TreeSet();
    
    /** Where to write the generated buildfile. */
    private static File failureBuildfile;
    
    /** The current running test project. Needed for addError()/addFailure(). */
    private Project currentTestProject;

    /** The current running build file. Needed for addError()/addFailure(). */
    private String currentBuildFile;
    
    
    /** No-arg constructor. */
    public FailureAntUnitListener() {
        super(new BaseAntUnitListener.SendLogTo(SendLogTo.ANT_LOG), "txt");
    }

    public void setFile(File file) {
        failureBuildfile = file;
    }

    public void startTestSuite(Project testProject, String buildFile) {
        super.startTestSuite(testProject, buildFile);
        currentTestProject = testProject;
        currentBuildFile = buildFile;
    }
    
    public void addError(String target, Throwable ae) {
        super.addError(target, ae);
        failedTests.add(new TestInfos(currentTestProject, currentBuildFile, target, ae.getMessage()));
    }
    
    public void addFailure(String target, AssertionFailedException ae) {
        super.addFailure(target, ae);
        failedTests.add(new TestInfos(currentTestProject, currentBuildFile, target, ae.getMessage()));
    } 
    
    /** not in use */
    public void endTest(String target) { 
    }

    public void endTestSuite(Project testProject, String buildFile) {
        StringBuffer sb = new StringBuffer();
        // <project> and antunit-target for direct run
        sb.append("<project default=\"antunit\" xmlns:au=\"antlib:org.apache.ant.antunit\">");
        sb.append(BR);
        sb.append(BR);
        sb.append("  <target name=\"antunit\">").append(BR);
        sb.append("    <au:antunit>").append(BR);
        sb.append("      <au:plainlistener/>").append(BR);
        sb.append("      <file file=\"${ant.file}\"/>").append(BR);
        sb.append("    </au:antunit>").append(BR);
        sb.append("  </target>").append(BR);
        sb.append(BR);
        sb.append(BR);
        
        // one target for each failed test
        int testNumber = 0;
        NumberFormat f = NumberFormat.getIntegerInstance();
        for (Iterator it = failedTests.iterator(); it.hasNext();) {
            sb.append("  <target name=\"test");
            sb.append(f.format(testNumber++));
            sb.append("\">").append(BR);
            TestInfos testInfos = (TestInfos) it.next();
            sb.append(testInfos);
            sb.append("  </target>").append(BR);
            sb.append(BR);
        }
        
        // close the <project>
        sb.append("</project>").append(BR);
        
        // write the whole file
        try {
            FileOutputStream fos = new FileOutputStream(failureBuildfile);
            fos.write(sb.toString().getBytes());
            FileUtils.close(fos);
        } catch (FileNotFoundException e) {
            throw new BuildException(e);
        } catch (IOException e) {
            throw new BuildException(e);
        }
    }
    
    
    /**
     * Class for collecting needed information about failed tests.
     */
    public class TestInfos implements Comparable {
        /** Does the project has a setUp target? */
        boolean projectHasSetup = false;
        
        /** Does the project has a tearDown target? */
        boolean projectHasTearDown = false;
        
        /** The called target. */
        String target;
        
        /** The buildfile of the project. */
        String buildfile;
        
        /** The error message which was shown. */
        String errorMessage;
        
        public TestInfos(Project project, String buildfile, String target, String errorMessage) {
            projectHasSetup = project.getTargets().containsKey("setUp");
            projectHasTearDown = project.getTargets().containsKey("tearDown");
            this.buildfile = buildfile;
            this.target = target; 
            this.errorMessage = errorMessage;
        }
        
        /** 
         * Creates an <ant> call according to the stored information. 
         * @see java.lang.Object#toString()
         */
        public String toString() {
            StringBuffer sb = new StringBuffer();
            // make the reader of the buildfile happy
            sb.append("    <!-- ");
            sb.append(errorMessage);
            sb.append(" -->").append(BR);
            // <ant antfile="" inheritAll="false">
            sb.append("    <ant ");
            sb.append("antfile=\"");
            sb.append(buildfile.replace('\\', '/'));
            sb.append("\" ");
            sb.append("inheritAll=\"false\">");
            sb.append(BR);
            // <target name=""/>
            if (projectHasSetup) {
                sb.append("      <target name=\"setUp\"/>").append(BR);
            }
            sb.append("      <target name=\"");
            sb.append(target);
            sb.append("\"/>");
            sb.append(BR);
            if (projectHasTearDown) {
                sb.append("      <target name=\"tearDown\"/>").append(BR);
            }
            // </ant>
            sb.append("    </ant>").append(BR);
            return sb.toString();
        }
        
        // Needed, so that a SortedSet could sort this class into the list.
        public int compareTo(Object other) {
            if (!(other instanceof TestInfos)) {
                return -1;
            } else {
                TestInfos that = (TestInfos)other;
                return this.toString().compareTo(that.toString());   
            }
        }
    }

}
