/*******************************************************************************
 * Copyright (C) 2007 The University of Manchester
 *
 *  Modifications to the initial code base are copyright of their
 *  respective authors, or their employers as appropriate.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1 of
 *  the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 ******************************************************************************/
package net.sf.taverna.t2.activities.wsdl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.wsdl.WSDLException;
import javax.xml.parsers.ParserConfigurationException;

import net.sf.taverna.t2.visit.VisitReport;
import net.sf.taverna.t2.visit.VisitReport.Status;
import net.sf.taverna.t2.workflowmodel.health.HealthCheck;
import net.sf.taverna.t2.workflowmodel.health.RemoteHealthChecker;
import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
import net.sf.taverna.t2.workflowmodel.processor.activity.DisabledActivity;
import net.sf.taverna.wsdl.parser.UnknownOperationException;
import net.sf.taverna.wsdl.parser.WSDLParser;

import org.xml.sax.SAXException;

import com.fasterxml.jackson.databind.JsonNode;

public class WSDLActivityHealthChecker extends RemoteHealthChecker {

	private Activity<?> activity;

	public boolean canVisit(Object subject) {
		if (subject == null) {
			return false;
		}
		if (subject instanceof WSDLActivity) {
			return true;
		}
		if (subject instanceof DisabledActivity) {
			return (((DisabledActivity) subject).getActivity() instanceof WSDLActivity);
		}
		return false;
	}

	public VisitReport visit(Object o, List<Object> ancestors) {
		List<VisitReport> reports = new ArrayList<VisitReport>();
		activity = (Activity<?>) o;
		String endpoint = null;

		WSDLParser parser;
		try {
			JsonNode configuration = null;
			if (activity instanceof WSDLActivity) {
				configuration = ((WSDLActivity)activity).getConfiguration();
			} else if (activity instanceof DisabledActivity) {
				configuration = (JsonNode) ((DisabledActivity) activity).getActivityConfiguration();
			}
			endpoint = configuration.get("operation").get("wsdl").asText();
			VisitReport wsdlEndpointReport = RemoteHealthChecker.contactEndpoint(activity, endpoint);
			reports.add(wsdlEndpointReport);
			if (!wsdlEndpointReport.getStatus().equals(Status.SEVERE)) {
			    parser = new WSDLParser(endpoint);

			    String operationName = configuration.get("operation").get("name").asText();
			    try {
                reports.add(testStyleAndUse(endpoint,
							    parser,
							    operationName));
				reports.add(testEndpoint(parser, operationName));
			    } catch (UnknownOperationException e) {
				VisitReport vr = new VisitReport(HealthCheck.getInstance(), activity,
							 "Operation not found", HealthCheck.UNKNOWN_OPERATION,
							 Status.SEVERE);
				vr.setProperty("operationName", operationName);
				vr.setProperty("endpoint", endpoint);
				reports.add(vr);
			    }
			}

		} catch (ParserConfigurationException e) {
			VisitReport vr = new VisitReport(HealthCheck.getInstance(), activity, "Invalid WSDL", HealthCheck.BAD_WSDL, Status.SEVERE);
			vr.setProperty("exception", e);
			vr.setProperty("endpoint", endpoint);
			reports.add(vr);
		} catch (WSDLException e) {
			VisitReport vr = new VisitReport(HealthCheck.getInstance(), activity, "Invalid WSDL", HealthCheck.BAD_WSDL, Status.SEVERE);
			vr.setProperty("exception", e);
			vr.setProperty("endpoint", endpoint);
			reports.add(vr);
		} catch (IOException e) {
			VisitReport vr = new VisitReport(HealthCheck.getInstance(), activity, "Read problem", HealthCheck.IO_PROBLEM, Status.SEVERE);
			vr.setProperty("exception", e);
			vr.setProperty("endpoint", endpoint);
			reports.add(vr);
		} catch (SAXException e) {
			VisitReport vr = new VisitReport(HealthCheck.getInstance(), activity, "Invalid WSDL", HealthCheck.BAD_WSDL, Status.SEVERE);
			vr.setProperty("exception", e);
			vr.setProperty("endpoint", endpoint);
			reports.add(vr);
		}

		Status status = VisitReport.getWorstStatus(reports);
		VisitReport report = new VisitReport(HealthCheck.getInstance(), activity, "WSDL Activity report", HealthCheck.NO_PROBLEM,
				status, reports);

		return report;
	}
	
	public static boolean checkStyleAndUse(String style, String use) {
		return !(style.equalsIgnoreCase("rpc") && use.equalsIgnoreCase("literal"));
	}

	private VisitReport testStyleAndUse(String endpoint, WSDLParser parser, String operationName) throws
                UnknownOperationException {
		VisitReport report;
		String style = parser.getStyle().toLowerCase();
		String use = "?";
		use = parser.getUse(operationName).toLowerCase();
		if (!checkStyleAndUse(style, use)) {
		    report = new VisitReport(HealthCheck.getInstance(), activity,
					     "Unsupported style", HealthCheck.UNSUPPORTED_STYLE,
					     Status.SEVERE);
		    report.setProperty("use", use);
		    report.setProperty("style", style);
		    report.setProperty("endpoint", endpoint);
		} else {
		    report = new VisitReport(HealthCheck.getInstance(), activity, style + "/"
					     + use + " is OK", HealthCheck.NO_PROBLEM, Status.OK);
		}
		return report;
	}

	private VisitReport testEndpoint(WSDLParser parser, String operationName) {
		List<VisitReport> reports = new ArrayList<VisitReport>();
		List<String> endpoints = parser
				.getOperationEndpointLocations(operationName);
		for (String endpoint : endpoints) {
			reports.add(RemoteHealthChecker.contactEndpoint(activity, endpoint));
		}

		Status status = VisitReport.getWorstStatus(reports);
		if (reports.size()==1) {
			return reports.get(0);
		}
		else if (reports.size()==0) {
		    VisitReport report = new VisitReport(HealthCheck.getInstance(), activity, "Service could not be located.", HealthCheck.NO_ENDPOINTS, Status.SEVERE);
		    report.setProperty("operationName", operationName);
		    return report;
		}
		else {
			return new VisitReport(HealthCheck.getInstance(), activity, "Endpoint tests",  HealthCheck.NO_PROBLEM, status, reports);
		}
	}

}
