package org.w3c.dbwg.wsdl.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
import org.apache.xerces.parsers.DOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class TestExamples {

	/**
	 * Run Ant script to iteratively test a toolkit for each example (barf dancing!) 
	 */
	
	private static String EXAMPLEURI = "http://www.w3.org/2002/ws/databinding/examples/6/09/";
	private static String EXAMPLENS = "http://www.w3.org/2002/ws/databinding/examples/6/09/";
	private static Vector<String> examples = new Vector<String>();  
	
	public static void main(String[] args) {

		String serviceURL = ""; // endpoint service
		if (args.length < 1) {
			System.out
			.println("Please supply the service URL.");
		} else {
			serviceURL = args[0];
		}

		// files used during processing 
		File outputOkFile = new File("example-results-ok.txt");
		File outputInvalidFile = new File("example-results-invalid.txt");
		URL exs = null;
		InputStream is = null;
		
		// get examples 
		String examplefile = EXAMPLEURI + "examples.xml";
		System.err
				.println("*** fetching examples.xml to extract the number of tests");
		try {
			exs = new URL(examplefile);
		} catch (MalformedURLException muex) {
			muex.printStackTrace();
			System.exit(1);
		}
		try {
			is = exs.openStream();
		} catch (IOException ioex) {
			ioex.printStackTrace();
			System.exit(1);
		}
		DOMParser parser = new DOMParser();
		BufferedReader bf = new BufferedReader(new InputStreamReader(is));
		InputSource ins = new InputSource(bf);
		try {
			parser.parse(ins);
		} catch (org.xml.sax.SAXException saxex) {
			saxex.printStackTrace();
			System.exit(1);
		} catch (IOException ioex) {
			ioex.printStackTrace();
			System.exit(1);
		}
		Document exdoc = parser.getDocument();
		NodeList inl = exdoc.getElementsByTagNameNS(EXAMPLENS, "instance");
		int totalTestsCount = inl.getLength();

		System.err.println("*** got " + totalTestsCount + " tests total");
		NodeList nl = exdoc.getElementsByTagNameNS(EXAMPLENS, "example");
		int cnt;
		for (cnt = 0; cnt < nl.getLength(); cnt++) {
			String exname = ((Element) nl.item(cnt)).getAttribute("xml:id");
			examples.add(exname);
			System.err.println(exname);
		}
		System.err.println("total examples=" + cnt);
		
		try {	
			// now iterate over the List of examples and test the WSDL from each service
			BufferedWriter outputOK = new BufferedWriter(new FileWriter(outputOkFile));
			BufferedWriter outputInvalid = new BufferedWriter(new FileWriter(outputInvalidFile));
			String os = System.getProperty("os.name");
			for (int i = 0; i < examples.size(); i++) {
				String example = (String) examples.get(i);
				// run an ant script to build,compile,deploy and test the WSDL
				// for each example
				Project project = new Project();
				project.init();
				DefaultLogger logger = new DefaultLogger();
				logger.setMessageOutputLevel(Project.MSG_INFO);
				logger.setErrorPrintStream(System.err);
				logger.setOutputPrintStream(System.out);
				project.addBuildListener(logger);
//				buildFile = new File(currentDir
//						+ "build_toolkit_test_for_example.xml");
				File buildFile = new File("build_toolkit_test_for_example.xml");
				ProjectHelper.configureProject(project, buildFile);
				project.setProperty("os", os); // pass the os to ant
				project.setProperty("example", example);
				project.setProperty("exampleNo", String.valueOf(i+1));
				project.setProperty("exampleMax", String.valueOf(cnt));
				try {
					project.executeTarget("init");
				} catch (BuildException be) {
					System.out.println("Ant build error=" + be.getMessage());
					outputInvalid.write(example);
					outputInvalid.newLine();
					outputInvalid.flush();
					continue;
				}
				// fetch WSDL for example - if this works then service is ok
				Document doc = null;
				System.out.println("endpointURL="+ serviceURL + example + "Port?wsdl");
				URL url = new URL(serviceURL + example + "Port?wsdl");
				try {
					HttpURLConnection conn = (HttpURLConnection) url
							.openConnection();
					DocumentBuilderFactory factory = DocumentBuilderFactory
							.newInstance();
					DocumentBuilder builder = factory.newDocumentBuilder();
					doc = builder.parse(conn.getInputStream());
					// check this is a valid WSDL file
					NodeList nodelist = doc.getElementsByTagName("definitions");
					if (nodelist == null) {
						outputInvalid.write(example);
						outputInvalid.newLine();
						outputInvalid.flush();
						System.out.println("Example " + example + " has not produced valid WSDL");
					} else {
						outputOK.write(example);
						outputOK.newLine();
						outputOK.flush();
						System.out.println("Example " + example + " OK!");
					}	
				} catch (Exception e) {
					System.out.println("checking WSDL error=" + e.getMessage());
					outputInvalid.write(example);
					outputInvalid.newLine();
					outputInvalid.flush();
					continue;
				}
			}
			outputInvalid.close();
			outputOK.close();
			
			// Now build the toolkit.xml which drives the testing of the web services 
			
			Project project = new Project();
			project.init();
			DefaultLogger logger = new DefaultLogger();
			logger.setMessageOutputLevel(Project.MSG_INFO);
			logger.setErrorPrintStream(System.err);
			logger.setOutputPrintStream(System.out);
			project.addBuildListener(logger);
			File buildFile = new File("build_toolkitxml.xml");
			ProjectHelper.configureProject(project, buildFile);
			project.setProperty("os", os); // pass the os to ant
			try {
				project.executeTarget("init");
			} catch (BuildException be) {
				System.out.println("Ant build error during toolkit.xml creation:" + be.getMessage());
			}
		
		} catch (Exception e) {
			System.out.println("Error during build war process:");
			System.out.println(e.getMessage());
		}
	}
}
