/*
 * This file is part of Nuts Framework.
 * Copyright(C) 2009-2012 Nuts Develop Team.
 *
 * Nuts Framework is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License any later version.
 * 
 * Nuts Framework 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Nuts Framework. If not, see <http://www.gnu.org/licenses/>.
 */
package nuts.aems.action.tools;

import nuts.core.io.Streams;
import nuts.exts.struts2.actions.CommonDataAccessAction;
import nuts.exts.struts2.util.StrutsContextUtils;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 */
public class CronJobsAction extends CommonDataAccessAction {

	public static class CronEntry {
		private String url;
		private String description;
		private String schedule;

		/**
		 * @return the url
		 */
		public String getUrl() {
			return url;
		}

		/**
		 * @param url the url to set
		 */
		public void setUrl(String url) {
			this.url = url;
		}

		/**
		 * @return the description
		 */
		public String getDescription() {
			return description;
		}

		/**
		 * @param description the description to set
		 */
		public void setDescription(String description) {
			this.description = description;
		}

		/**
		 * @return the schedule
		 */
		public String getSchedule() {
			return schedule;
		}

		/**
		 * @param schedule the schedule to set
		 */
		public void setSchedule(String schedule) {
			this.schedule = schedule;
		}
		
		public String toString() {
			StringBuilder sb = new StringBuilder();

			sb.append("{ ");
			sb.append("url: ").append(url);
			sb.append(", ");
			sb.append("description: ").append(description);
			sb.append(", ");
			sb.append("schedule: ").append(schedule);
			sb.append(" }");
			
			return sb.toString();
		}
	}

	private String cronFile = "/WEB-INF/cron.xml";
	private List<CronEntry> cronEntries;

	/**
	 * @return the cronFile
	 */
	public String getCronFile() {
		return cronFile;
	}

	/**
	 * @param cronFile the cronFile to set
	 */
	public void setCronFile(String cronFile) {
		this.cronFile = cronFile;
	}

	/**
	 * @return the cronEntries
	 */
	public List<CronEntry> getCronEntries() {
		return cronEntries;
	}

	/**
	 * constructor
	 */
	public CronJobsAction() {
	}

	/**
	 * execute
	 * 
	 * @return SUCCESS
	 * @throws Exception if an error occurs
	 */
	public String execute() throws Exception {
		String path = StrutsContextUtils.getServletContext().getRealPath(cronFile);

		InputStream is = null;
		try {
			is = new FileInputStream(path);
			DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = dbfactory.newDocumentBuilder();
			Document doc = builder.parse(is);
			Element root = doc.getDocumentElement();
			NodeList nl = root.getChildNodes();
			
			cronEntries = new ArrayList<CronEntry>(nl.getLength());
			
			for (int i = 0; i < nl.getLength(); i++) {
				Node n = nl.item(i);
				if (n.getNodeName().equals("cron")) {
					CronEntry ce = new CronEntry();
					
					NodeList cnl = n.getChildNodes();
					for (int j = 0; j < cnl.getLength(); j++) {
						Node c = cnl.item(j);
						if (c.getNodeName().equals("url")) {
							ce.setUrl(c.getTextContent());
						}
						else if (c.getNodeName().equals("description")) {
							ce.setDescription(c.getTextContent());
						}
						else if (c.getNodeName().equals("schedule")) {
							ce.setSchedule(c.getTextContent());
						}
					}
					cronEntries.add(ce);
				}
			}
		}
		finally {
			Streams.safeClose(is);
		}
		return INPUT;
	}
}
