//
// https://www.ramecera.it/myscrewdriver.html
// e-mail: screwdriver@ramecera.it
//
/* This program and the accompanying materials are made available under
 * the terms of the Eclipse Public License v1.0 which accompanies this
 * distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html */
package it.ramecera.screwdriver.component;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;

import it.ramecera.salad.everyday.Candies;
import it.ramecera.salad.everyday.ExactException;
import it.ramecera.salad.everyday.Mix;
import it.ramecera.salad.everyday.Strings;
import it.ramecera.salad.everyday.Universal;
import it.ramecera.salad.file.Abacus;
import it.ramecera.salad.file.Equipment;
import it.ramecera.screwdriver.CandyScrew;
import it.ramecera.screwdriver.Markup;
import it.ramecera.screwdriver.Skill;
import it.ramecera.screwdriver.Train;

/**
 * <p>
 * Creation date: 2020-04-09<br>
 * Last updated: 2020-06-20<br>
 * Company: Ramecera™
 * </p>
 * 
 * @author Massimo Maglioni
 *         <p>
 *         Description:
 *         </p>
 */
final public class Dispatcher_xml extends FileComponent {

	/** @param skill together with the descriptive data of the
	 * @param snippetG application */
	public Dispatcher_xml(Skill skill, String snippetG) {
		super();
		this.skill = skill;
		this.snippetG = snippetG;
	}

	/** @throws ExactException exception specified by a numeric code */
	@Override
	final public void synthesis(HashMap<String, Markup> markupE,
			List<Train> trainE, CandyScrew candyScrew)

			throws FileNotFoundException, IOException, ExactException {

		String dispatcherG = skill.candies.snippetsYS + snippetG;
		producedMaterial = Equipment.oneString(dispatcherG)
				+ Candies.LF;
		String xmlns_altri = "";
		String sdefauto = "";
		String location_altri = "";
		if (skill.defaultAutowire) {
			sdefauto += "default-autowire = \"" + markupE.get(
					"sdefauto").recurrenceE.get(0).locomotor.text
					+ "\"";
		}
		if (skill.springSecurity) {
			xmlns_altri += Candies.LF + Candies.TABS
					+ "xmlns:s=\"http://www.springframework.org/schema/security\"";
			location_altri += Candies.LF + Candies.TABS + Candies.TABS
					+ Candies.TABS
					+ "http://www.springframework.org/schema/security";
			location_altri += Candies.LF + Candies.TABS + Candies.TABS
					+ Candies.TABS
					+ "http://www.springframework.org/schema/secu"
					+ "rity/spring-security-"
					+ skill.springSecurityReductVersion + ".xsd";
		}
		if (skill.webFlow) {
			xmlns_altri += Candies.LF + Candies.TABS
					+ "xmlns:webflow-config=\"http://www.spring"
					+ "framework.org/schema/webflow-config\"";
			location_altri += Candies.LF + Candies.TABS + Candies.TABS
					+ Candies.TABS + "http://www.springframe"
					+ "work.org/schema/webflow-config";
			location_altri += Candies.LF + Candies.TABS + Candies.TABS
					+ Candies.TABS
					+ "http://www.springframework.org/schema/web"
					+ "flow-config/spring-webflow-config-2.3.xsd";
		}
		location_altri += Candies.LF + Candies.TABS + Candies.TABS
				+ Candies.TABS
				+ "http://www.springframework.org/schema/jdbc";
		location_altri += Candies.LF + Candies.TABS + Candies.TABS
				+ Candies.TABS
				+ "http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd";
		producedMaterial += Candies.TABS + "<mvc:annotation-driven";
		if (skill.matrixVariables & skill.springVersion1m == 4) {
			producedMaterial += " enable-matrix-variables=\"true\"";
		} else if (skill.matrixVariables & skill.springVersion
				.startsWith("3.2")) {
			producedMaterial += " enableMatrixVariables=\"true\"";
		}
		if (skill.springValid | skill.hiberValid) {
			producedMaterial += " validator=\"validator\"";
		}
		producedMaterial += ">" + Candies.LF;
		if (skill.springSecurity) {
			producedMaterial += Candies.TABS + Candies.TABS
					+ "<mvc:argument-resolvers>" + Candies.LF;
			producedMaterial += Candies.TABS + Candies.TABS
					+ Candies.TABS
					+ "<bean class=\"+zoccolo+.web.resolver"
					+ ".LoggedUserMethodArgumentResolver\" />"
					+ Candies.LF;
			producedMaterial += Candies.TABS + Candies.TABS
					+ "</mvc:argument-resolvers>" + Candies.LF;
		}
		producedMaterial += Candies.TABS + "</mvc:annotation-driven>"
				+ Candies.LF;
		producedMaterial += Candies.TABS
				+ "<context:component-scan base-package=\""
				+ Candies.LF;
		producedMaterial += Candies.TABS + Candies.TABS
				+ "+zoccolo+.web;" + Candies.LF;
		if (skill.springSecurity) {
			producedMaterial += Candies.TABS + Candies.TABS
					+ "+zoccolo+.security;" + Candies.LF;
		}
		/* no need to mention sub packages */
		producedMaterial += Candies.TABS + "\"/>" + Candies.LF;
		producedMaterial += Candies.TABS
				+ "<context:property-placeholder"
				+ " location=\"classpath:config.properties\" />"
				+ Candies.LF;
		if (skill.springSecurity) {
			producedMaterial += Candies.TABS
					+ "<s:global-method-security pre-post"
					+ "-annotations=\"enabled\" />" + Candies.LF;
		}
		producedMaterial += Candies.LF;
		/* RESOURCES */
		for (int i = 0; i < markupE.get("sreso").recurrenceE
				.size(); i++) {
			String risorsa = markupE.get("sreso").recurrenceE.get(
					i).locomotor.text;
			if (i == 0 & risorsa.length() == 0) {
				producedMaterial += Candies.TABS
						+ "<mvc:resources location=\"/resources/\" mapping"
						+ "=\"/resources/**\"/>" + Candies.LF;
				if (markupE.get("sreso").recurrenceE.size() > 1) {
					ExactException ce = new ExactException(
							"The \"sreso+\" markup without data is incompatible with other sreso+.",
							1000, this.getClass().getName(), "");
					throw ce;
				}
			} else if (i > 0 & risorsa.length() == 0) {
				ExactException ce = new ExactException(
						"The \"sreso+\" markup without data is incompatible with other sreso+.",
						1001, this.getClass().getName(), "");
				throw ce;
			} else {
				producedMaterial += Candies.TABS
						+ "<mvc:resources location=\"/resources/"
						+ risorsa + "/\" mapping=\"/resources/"
						+ risorsa + "/**\"/>" + Candies.LF + Candies.LF;
				skill.buildDirectory(skill.webAppResourcesY + "/"
						+ risorsa);
			}
		}
		producedMaterial += Candies.TABS
				+ "<mvc:default-servlet-handler />" + Candies.LF
				+ Candies.LF;
		if (skill.robots) {
			producedMaterial += Candies.TABS
					+ "<mvc:resources location=\"/\" mapping=\"/robots.txt\"/>"
					+ Candies.LF;
			File robots = new File(skill.candies.snippetsYS
					+ "robots.txt");
			if (!robots.exists() | !robots.isFile()) {
				ExactException ce = new ExactException(
						"Among the snippets the file "
								+ "«robots.txt» does not exist.", 1002,
						this.getClass().getName(), "");
				throw ce;
			} else {
				Abacus.copyFile(robots, new File(skill.webAppG + "/"
						+ "robots.txt"));
			}
		}
		/* INTERCEPTOR */
		String newInterceptor = skill.javaWebY + "/interceptor";
		File screwInterceptor = null;
		if (skill.interceptor) {
			skill.buildDirectory(newInterceptor);
			producedMaterial += Candies.LF + Candies.TABS
					+ "<mvc:interceptors>";
			screwInterceptor = new File(skill.candies.snippetsYS
					+ "java/ScrewInterceptor.java");
			if (!screwInterceptor.exists() | !screwInterceptor
					.isFile()) {
				ExactException ce = new ExactException(
						"Among the snippets the file "
								+ "«ScrewInterceptor.java» does not exist.",
						1003, this.getClass().getName(), "");
				throw ce;
			}
		}
		for (int i = 0; i < markupE.get("sinterce").recurrenceE
				.size(); i++) {
			String nomeFile = Mix.uppercaseFirstChar(markupE.get(
					"sinterce").recurrenceE.get(i).locomotor.text);
			FileComponent.addClass("ScrewInterceptor.java",
					newInterceptor, nomeFile, skill.candies,
					recycleBinY, skill, -1, markupE, "java");
			producedMaterial += Candies.LF + Candies.TABS + Candies.TABS
					+ "<bean class= \"" + skill.pckg
					+ ".web.interceptor." + nomeFile + "\" />";
		}
		if (skill.interceptor) {
			if (skill.i18n) {
				producedMaterial += Candies.LF + Candies.TABS
						+ Candies.TABS
						+ "<bean class= \"org.springframework.web.servlet"
						+ ".i18n.LocaleChangeInterceptor\">";
				producedMaterial += Candies.LF + Candies.TABS
						+ Candies.TABS + Candies.TABS
						+ "<property name=\"paramName\""
						+ " value=\"language\" />";
				producedMaterial += Candies.LF + Candies.TABS
						+ Candies.TABS + "</bean>" + Candies.LF;
			}
			producedMaterial += Candies.LF + Candies.TABS
					+ "</mvc:interceptors>" + Candies.LF + Candies.LF;
		}
		if (skill.viewController) {
			producedMaterial += Candies.LF;
			for (int i = 0; i < markupE.get("sieco").recurrenceE
					.size(); i++) {
				String[] s = (String[]) markupE.get("sieco").recurrenceE
						.get(i).locomotor.substance;
				producedMaterial += Candies.TABS
						+ "<mvc:view-controller path=\"" + s[0] + "/"
						+ s[1] + "\" view-name=\"" + s[0] + "/" + s[1]
						+ "\" />" + Candies.LF + Candies.LF;
			}
		}
		if (skill.tiles) {
			String[] qualificatoreE = skill.tilesVersion.split("\\x2e");
			String g = skill.candies.snippetsYS
					+ "corpoDispatcherTiles_" + qualificatoreE[0]
					+ ".txt";
			producedMaterial += Equipment.oneString(g) + Candies.LF;
		} else {
			String g = skill.candies.snippetsYS + "ViewResolver.txt";
			producedMaterial += Equipment.oneString(g) + Candies.LF;
		}
		if (skill.i18n) {
			producedMaterial += Candies.LF + Candies.TABS
					+ "<bean id=\"localeResolver\" class=\"org"
					+ ".springframework.web.servlet.i18n"
					+ ".SessionLocaleResolver\">";
			producedMaterial += Candies.LF + Candies.TABS + Candies.TABS
					+ "<property name=\"defaultLocale\" value=\""
					+ Universal.languageE[skill.defaulan][1]
							.toLowerCase() + "\" />";
			producedMaterial += Candies.LF + Candies.TABS + "</bean>"
					+ Candies.LF + Candies.LF;
		}
		if (skill.springValid | skill.hiberValid) {
			producedMaterial += Candies.TABS + "<bean id=\"validator\""
					+ " class=\"org.springframework.validation.beanvalidation.LocalValidatorFactoryBean\">"
					+ Candies.LF;
			producedMaterial += Candies.TABS + Candies.TABS
					+ "<property name=\"validationMessageSource\""
					+ " ref=\"messagesScrewValid\" />" + Candies.LF;
			producedMaterial += Candies.TABS + "</bean>" + Candies.LF;
			producedMaterial += Candies.TABS
					+ "<bean id=\"messagesScrewValid\""
					+ " class=\"org.springframework.context.support.ResourceBundleMessageSource\">"
					+ Candies.LF;
			producedMaterial += Candies.TABS + Candies.TABS
					+ "<property name=\"basename\" value=\"messagesScrewValid\"/>"
					+ Candies.LF;
			producedMaterial += Candies.TABS + "</bean>" + Candies.LF;
		}
		if (skill.prettyPrint) {
			String g = skill.candies.snippetsYS + "jacksonView.txt";
			producedMaterial += Equipment.oneString(g) + Candies.LF
					+ Candies.LF;
		}
		/* FUTURE RELEASE N6 */
		// if (skill.embedded) {
		// embeddedMaker();
		// }
		producedMaterial += "<!-- screwdriver_knife -->" + Candies.LF;
		/* WE COOK EVERYTHING */
		producedMaterial = Strings.replaceFirst(producedMaterial,
				"+xmlns_altri+", xmlns_altri);
		producedMaterial = Strings.replaceFirst(producedMaterial,
				"+default-autowire+", sdefauto);
		producedMaterial = Strings.replaceFirst(producedMaterial,
				"+location_altri+", location_altri);
		producedMaterial = producedMaterial.replaceAll(
				"\\x2bzoccolo\\x2b", skill.pckg);
		producedMaterial += "</beans>";
	}

	/* FUTURE RELEASE N6 */
	// final private void embeddedMaker()
	//
	// throws ExactException {
	//
	// Iterator<String> iterator = skill.dbmsE.iterator();
	// while (iterator.hasNext()) {
	// producedMaterial += Candies.TABS
	// + "<jdbc:embedded-database id=\"dataSource\" type=\""
	// + iterator.next() + "\">" + Candies.LF;
	// if (skill.ddl != null) {
	// for (int i = 0; i < skill.ddl.length; i++) {
	// producedMaterial += Candies.TABS + Candies.TABS
	// + "<jdbc:script location=\"classpath:/database/"
	// + Mix.inizialeMinuscola((String) (iterator
	// .next())) + "/" + skill.ddl[i]
	// + ".sql\" />" + Candies.LF;
	// Equipment.scriviFileVuoto(skill.mainResources
	// + "/database/" + Mix.lowercaseInitial(
	// (String) (iterator.next())) + "/"
	// + skill.ddl[i] + ".sql");
	// }
	// }
	// }
	// producedMaterial += Candies.TABS + "</jdbc:embedded-database>"
	// + Candies.LF;
	// producedMaterial += Candies.TABS
	// + "<bean id=\"transactionManager\"" + Candies.LF;
	// producedMaterial += Candies.TABS + Candies.TABS
	// + "class=\"org.springframework.jdbc.datasource"
	// + ".DataSourceTransactionManager\"" + Candies.LF;
	// producedMaterial += Candies.TABS + Candies.TABS
	// + "p:dataSource-ref=\"dataSource\" />" + Candies.LF;
	// producedMaterial += Candies.TABS + "<bean id=\"jdbcTemplate\""
	// + Candies.LF;
	// producedMaterial += Candies.TABS + Candies.TABS
	// + "class=\"org.springframework.jdbc.core.JdbcTemplate\""
	// + Candies.LF;
	// producedMaterial += Candies.TABS + Candies.TABS
	// + "p:dataSource-ref=\"dataSource\" />" + Candies.LF;
	// }

	/* written only to comply with the abstract class FileComponent */
	@SuppressWarnings("javadoc")
	@Override
	/** @param markupE the list of markups
	 * @param skill together with the characteristics of the application
	 * @param trash file where the deleted files are moved
	 * @throws ExactException exception specified by a numeric code */
	public void directory(HashMap<String, Markup> markupE)

			throws ExactException {

	}
}
