/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed 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 misc.detailed;

import org.junit.Before;
import org.junit.Test;
import tools.ant.*;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Target;
import org.apache.tools.ant.BuildException;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;

/**
 * Date: Feb 8, 2005
 * Time: 11:30:24 AM
 */
public class SampleRunner {

    @Before
    protected void setUp() throws Exception {
        proj = new Project();
        proj.setName("Samples Task Tests");
        XMLBEANS_HOME = proj.getBaseDir().getAbsolutePath();
        samples = new ArrayList();
        runSampleTest = new SamplesBuildFileTest();
    }

    @Test
    public void testSamples() throws Exception {
        loadSampleDirs(new File("./samples"));
        ArrayList exceptions = new ArrayList();
        for (int i = 0; i < samples.size(); i++)
        {

            runSampleTest.call_samples_task(
                ((File) samples.get(i)).getAbsolutePath()
                , "test");
            BuildException e;
            if ((e = runSampleTest.getAnyExceptions()) != null)
            {
                exceptions.add(((File) samples.get(i)).getAbsolutePath());
                exceptions.add(e.getException());
            }
        }
        if (exceptions.size() != 0)
            throw new RuntimeException(getMessageFromExceptions(exceptions));

    }

    private String getMessageFromExceptions(ArrayList ex)
    {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < ex.size(); i += 2)
        {
            sb.append("\n\nFILE:" + (String) ex.get(i));
            sb.append(
                "\n **Error: " + ((BuildException) ex.get(i + 1)).getMessage());
        }
        return sb.toString();
    }

    private void loadSampleDirs(File dir)
    {
        assert dir != null && dir.exists();
        File[] files = dir.listFiles(new BuildFilter());
        assert files.length == 1;
        samples.add(files[0]);

    }

    private class BuildFilter
        implements FilenameFilter
    {
        public boolean accept(File file, String name)
        {
            return name.equals("build.xml");
        }
    }

    private class SamplesBuildFileTest extends BuildFileTest {
        public void call_samples_task(String projectPath, String taskName)
        {
            configureProject(projectPath);
            Project proj = getProject();
            proj.setProperty("xmlbeans.home", XMLBEANS_HOME);
            executeTarget(proj.getDefaultTarget());
        }

        public BuildException getAnyExceptions()
            throws Exception
        {
            return this.getBuildException();
        }
    }

    ArrayList samples;
    Project proj;
    Target target;
    String XMLBEANS_HOME;
    SamplesBuildFileTest runSampleTest;

}
