/**
 * **********************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 *
 * Copyright 2009, 2010 Oracle and/or its affiliates. All rights reserved.
 *
 * Use is subject to license terms.
 *
 * 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. You can also
 * obtain a copy of the License at http://odftoolkit.org/docs/license.txt
 *
 * 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 schema2template.example.odf;

import com.sun.msv.grammar.Expression;
import com.sun.msv.reader.trex.ng.RELAXNGReader;
import java.io.File;
import java.io.FileWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.SAXParserFactory;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import schema2template.OutputFileListEntry;
import schema2template.OutputFileListHandler;
import schema2template.model.XMLModel;

/**
 * Three ODF examples in one:
 *  1) Create an ODF Reference in HTMLl
 *  2) Create Source Code
 *  3) Create simple ODF Python source
 *
 */
public class OdfHelper {

	private static final Logger LOG = Logger.getLogger(OdfHelper.class.getName());
	public static final Boolean DEBUG = Boolean.FALSE;
	/** Expresses the amount of elements in ODF 1.1. There are some issues in the schema that have to be fixed before the full number can be returned by MSV:
	Reference table-table-template is never used, therefore several elements are not taking into account::
	"table:body"
	"table:even-columns"
	"table:even-rows"
	"table:first-column"
	"table:first-row"
	"table:last-column"
	"table:last-row"
	"table:odd-columns"
	"table:odd-rows"
	"table:table-template"
	NOTE: Ignoring the '*' there can be 525 elements parsed, but with fixed schema it should be 535. */
	public static final int ODF11_ELEMENT_NUMBER = 525; //ToDo: 535 - by search/Replace using RNGSchema and tools, prior exchange <name> to element or attribute declaration
	public static final int ODF12_ELEMENT_NUMBER = 598;
	/** Expresses the amount of attributes in ODF 1.1. There are some issues in the schema that have to be fixed before the full number can be returned by MSV:
	Following references are never used, therefore its attribute is not taking into account::
	draw-glue-points-attlist	with "draw:escape-direction"
	office-process-content		with "office:process-content" (DEPRECATED in ODF1.2 only on foreign elements)

	Following attributes are member of the not referenced element "table:table-template":
	"text:first-row-end-column"
	"text:first-row-start-column"
	"text:last-row-end-column"
	"text:last-row-start-column"
	"text:paragraph-style-name"

	NOTE: Ignoring the '*' there can be 1162 elements parsed, but with fixed schema it should be 1169. */
	public static final int ODF11_ATTRIBUTE_NUMBER = 1162; //ToDo: 1169 - by search/Replace using RNGSchema and tools, prior exchange <name> to element or attribute declaration
	public static final int ODF12_ATTRIBUTE_NUMBER = 1300; //in RNG 1301 as there is one deprecated attribute on foreign elements not referenced (ie. @office:process-content)
	private static String odfDomResourceDir;
	private static String odfPkgResourceDir;
	private static String odfPythonResourceDir;
	private static String odfReferenceResourceDir;
    private static String odfSchemaResourceDir;
	private static String outputRoot;
	public static final String INPUT_ROOT = "target" + File.separator + "odf-schemas";
	public static final String TEST_REFERENCE_DIR = "target" + File.separator + "test-classes" + File.separator
			+ "examples" + File.separator + "odf";
	public static final String TEST_INPUT_ROOT = "target" + File.separator + "classes" + File.separator
			+ "examples" + File.separator + "odf";
	public static final String ODF10_RNG_FILE_NAME = "OpenDocument-strict-schema-v1.0-os.rng";
	public static final String ODF11_RNG_FILE_NAME = "OpenDocument-strict-schema-v1.1.rng";
	public static final String ODF12_RNG_FILE_NAME = "OpenDocument-v1.2-os-schema.rng";
	public static final String ODF12_SIGNATURE_RNG_FILE_NAME = "OpenDocument-v1.2-os-dsig-schema.rng";
	public static final String ODF12_MANIFEST_RNG_FILE_NAME = "OpenDocument-v1.2-os-manifest-schema.rng";
	static String odf12RngFile;
	static String odf12SignatureRngFile;
	static String odf12ManifestRngFile;
	static String odf11RngFile;
	static String odf10RngFile;
	private static String mConfigFile;
	private static final String REFERENCE_OUTPUT_FILES_TEMPLATE = "dom-output-files.vm";
	private static final String REFERENCE_OUTPUT_FILES = "target" + File.separator + "reference-output-files.xml";
	private static final String PYTHON_OUTPUT_FILES_TEMPLATE = "dom-output-files.vm";
	private static final String PYTHON_OUTPUT_FILES = "target" + File.separator + "python-output-files.xml";
	private static final String DOM_OUTPUT_FILES_TEMPLATE = "dom-output-files.vm";
	private static final String DOM_OUTPUT_FILES = "target" + File.separator + "dom-output-files.xml";
	private static final String PKG_MANIFEST_OUTPUT_FILES_TEMPLATE = "pkg-manifest-output-files.vm";
	private static final String PKG_MANIFEST_OUTPUT_FILES = "target" + File.separator + "pkg-manifest-output-files.xml";
	private static final String PKG_DSIG_OUTPUT_FILES_TEMPLATE = "pkg-dsig-output-files.vm";
	private static final String PKG_DSIG_OUTPUT_FILES = "target" + File.separator + "pkg-dsig-output-files.xml";
	private static XMLModel mOdf12SignatureSchemaModel;
	private static XMLModel mOdf12ManifestSchemaModel;
	private static XMLModel mOdf12SchemaModel;
	private static XMLModel mOdf11SchemaModel;
	private static OdfModel mOdfModel;
	private static SourceCodeModel mJavaModel;
	private static Expression mOdf12SignatureRoot;
	private static Expression mOdf12ManifestRoot;
	private static Expression mOdf12Root;
	private static Expression mOdf11Root;

	public OdfHelper(String domResourceRoot, String odf12SchemaFile, String odf11SchemaFile, String pkgResourceRoot, String odf12SignatureSchemaFile, String odf12ManifestSchemaFile, String targetRoot, String configFile) {
		odfDomResourceDir = domResourceRoot;
		odf12RngFile = odf12SchemaFile;
		odf11RngFile = odf11SchemaFile;
		odfPkgResourceDir = pkgResourceRoot;
		odf12SignatureRngFile = odf12SignatureSchemaFile;
		odf12ManifestRngFile = odf12ManifestSchemaFile;
		outputRoot = targetRoot;
		mConfigFile = configFile;
	}

	static {
		odfDomResourceDir = TEST_INPUT_ROOT + File.separator + "odfdom-java" + File.separator + "dom";
		odfPkgResourceDir = TEST_INPUT_ROOT + File.separator + "odfdom-java" + File.separator + "pkg";
		odfPythonResourceDir = TEST_INPUT_ROOT + File.separator + "odfdom-python";
		odfReferenceResourceDir = TEST_INPUT_ROOT + File.separator + "odf-reference";
        odfSchemaResourceDir = TEST_INPUT_ROOT + File.separator + "odf-schemas";
		odf12SignatureRngFile = odfSchemaResourceDir + File.separator + ODF12_SIGNATURE_RNG_FILE_NAME;
		odf12ManifestRngFile = odfSchemaResourceDir + File.separator + ODF12_MANIFEST_RNG_FILE_NAME;
		odf12RngFile = odfSchemaResourceDir + File.separator + ODF12_RNG_FILE_NAME;
		odf11RngFile = odfSchemaResourceDir + File.separator + ODF11_RNG_FILE_NAME;
		odf10RngFile = odfSchemaResourceDir + File.separator + ODF10_RNG_FILE_NAME;
		outputRoot = "target";
		mConfigFile = TEST_INPUT_ROOT + File.separator + "config.xml";
	}

	public void start() throws Exception {
		LOG.info("Starting code generation:");
		initialize();

		// ODF 1.2 Code Generation
        fillTemplates(odfDomResourceDir, mOdf12Root, DOM_OUTPUT_FILES_TEMPLATE, DOM_OUTPUT_FILES, mOdf12SchemaModel);
        fillTemplates(odfPkgResourceDir, mOdf12ManifestRoot, PKG_MANIFEST_OUTPUT_FILES_TEMPLATE, PKG_MANIFEST_OUTPUT_FILES, mOdf12ManifestSchemaModel);
        fillTemplates(odfPkgResourceDir, mOdf12SignatureRoot, PKG_DSIG_OUTPUT_FILES_TEMPLATE, PKG_DSIG_OUTPUT_FILES, mOdf12SignatureSchemaModel);
	}

	public static void main(String[] args) throws Exception {
		LOG.info("Starting code generation:");
		initialize();

		// ODF 1.2 HTML Reference (yet without BNF nor images)
		fillTemplates(odfReferenceResourceDir, mOdf12Root, REFERENCE_OUTPUT_FILES_TEMPLATE, REFERENCE_OUTPUT_FILES, mOdf12SchemaModel);
		// ODF 1.2 Python (The generated Python source is from a former colleague and might not work any longer..)
		fillTemplates(odfPythonResourceDir, mOdf12Root, PYTHON_OUTPUT_FILES_TEMPLATE, PYTHON_OUTPUT_FILES, mOdf12SchemaModel);

		// ODF 1.2 Code Generation
		fillTemplates(odfDomResourceDir, mOdf12Root, DOM_OUTPUT_FILES_TEMPLATE, DOM_OUTPUT_FILES, mOdf12SchemaModel);
        fillTemplates(odfPkgResourceDir, mOdf12ManifestRoot, PKG_MANIFEST_OUTPUT_FILES_TEMPLATE, PKG_MANIFEST_OUTPUT_FILES, mOdf12ManifestSchemaModel);
		fillTemplates(odfPkgResourceDir, mOdf12SignatureRoot, PKG_DSIG_OUTPUT_FILES_TEMPLATE, PKG_DSIG_OUTPUT_FILES, mOdf12SignatureSchemaModel);
	}

	private static void initialize() throws Exception {
		LOG.info("Starting initilization..");
		// calling MSV to parse the ODF 1.2 DSIG RelaxNG, returning a tree
		mOdf12SignatureRoot = loadSchema(new File(odf12SignatureRngFile));
		// calling MSV to parse the ODF 1.2 Manifest RelaxNG, returning a tree
		mOdf12ManifestRoot = loadSchema(new File(odf12ManifestRngFile));
		// calling MSV to parse the ODF 1.2 RelaxNG, returning a tree
		mOdf12Root = loadSchema(new File(odf12RngFile));
		// calling MSV to parse the ODF 1.1 RelaxNG, returning a tree
		mOdf11Root = loadSchema(new File(odf11RngFile));

		// Read config.xml 2DO WHAT IS ODFDOM GENERATOR CONFIG FILE
		// Manual added Java specific info - Base class for inheritance
		Map<String, String> elementToBaseNameMap = new HashMap<String, String>();
		// Manual added ODF specific info - style family mapping
		Map<String, List<String>> elementStyleFamiliesMap = new HashMap<String, List<String>>();
		// 2DO - still existent? -- Manual added Java specific info - mapping ODF datatype to Java datatype  -> {odfValueType, javaConversionClassName}
		Map<String, String[]> datatypeValueAndConversionMap = new HashMap<String, String[]>();
		Map<String, OdfModel.AttributeDefaults> attributeDefaultMap = new HashMap<String, OdfModel.AttributeDefaults>();
		OdfConfigFileHandler.readConfigFile(new File(mConfigFile), elementToBaseNameMap, attributeDefaultMap, elementStyleFamiliesMap, datatypeValueAndConversionMap);

		mOdf12SignatureSchemaModel = new XMLModel(mOdf12SignatureRoot);
		mOdf12ManifestSchemaModel = new XMLModel(mOdf12ManifestRoot);
		mOdf12SchemaModel = new XMLModel(mOdf12Root);
		mOdf11SchemaModel = new XMLModel(mOdf11Root);
		mOdfModel = new OdfModel(elementStyleFamiliesMap, attributeDefaultMap);
		// Needed for the base classes - common attributes are being moved into the base classes
		mJavaModel = new SourceCodeModel(mOdf12SchemaModel, mOdf12SignatureSchemaModel, mOdf12ManifestSchemaModel, mOdfModel, elementToBaseNameMap, datatypeValueAndConversionMap);
		LOG.info("Finished initilization..");
	}

	private static void fillTemplates(String sourceDir, Expression root, String outputRuleTemplate, String outputRuleFile, XMLModel model) throws Exception {
		// intialising template engine (ie. Velocity)
		Properties props = new Properties();
		props.setProperty("file.resource.loader.path", sourceDir);
		VelocityEngine ve = new VelocityEngine(props);
		ve.init();

		// Create output-files.xml
		createOutputFileList(ve, outputRuleTemplate, outputRuleFile, model);
		LOG.info("output-files.xml created done.");

		// Process output-files.xml, create output files
		LOG.fine("Processing output files... ");
		processFileList(ve, root, outputRuleFile, model);
		LOG.fine("DONE.\n");
	}

	/**
	 * Load and parse the ODF 1.0 Schema.
	 *
	 * @return MSV Expression Tree of ODF 1.0 RelaxNG schema (more specific: The
	 * tree's MSV root expression)
	 * @throws Exception
	 */
	public static Expression loadSchemaODF10() throws Exception {
		return loadSchema(new File(odf10RngFile));
	}

	/**
	 * Load and parse the ODF 1.1 Schema.
	 *
	 * @return MSV Expression Tree of ODF 1.1 RelaxNG schema (more specific: The
	 * tree's MSV root expression)
	 * @throws Exception
	 */
	public static Expression loadSchemaODF11() throws Exception {
		return loadSchema(new File(odf11RngFile));
	}

	/**
	 * Load and parse the ODF 1.2 Schema.
	 *
	 * @return MSV Expression Tree of ODF 1.2 RelaxNG schema (more specific: The
	 * tree's MSV root expression)
	 * @throws Exception
	 */
	public static Expression loadSchemaODF12() throws Exception {
		return loadSchema(new File(odf12RngFile));
	}

	/**
	 * Load and parse a Schema from File.
	 *
	 * @param rngFile
	 * @return MSV Expression Tree (more specific: The tree's MSV root
	 * expression)
	 * @throws Exception
	 */
	public static Expression loadSchema(File rngFile) throws Exception {

   		SAXParserFactory saxFactory = new org.apache.xerces.jaxp.SAXParserFactoryImpl();
		saxFactory.setNamespaceAware(true);
		saxFactory.setValidating(false);
		try {
			saxFactory.setXIncludeAware(false);
			saxFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
			// removing potential vulnerability: see https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing
			saxFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
			saxFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
			saxFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
		} catch (Exception ex) {
			Logger.getLogger(OdfHelper.class.getName()).log(Level.SEVERE, null, ex);
			throw new RuntimeException();
		}

		// Parsing the Schema with MSV
		String absolutePath = rngFile.getAbsolutePath();
		com.sun.msv.reader.util.IgnoreController ignoreController = new com.sun.msv.reader.util.IgnoreController();
		Expression root = RELAXNGReader.parse(absolutePath, saxFactory, ignoreController).getTopLevel();


		if (root == null) {
			throw new Exception("Schema could not be parsed.");
		}
		return root;
	}

	private static VelocityContext getContext(String contextStr, String param) {
		VelocityContext context = new VelocityContext();
		context.put("oldmodel", mOdf11SchemaModel);
		context.put("odfmodel", mOdfModel);
		context.put("javamodel", mJavaModel);
		context.put("context", contextStr);
		context.put("param", param);
		return context;
	}

	private static void createOutputFileList(VelocityEngine ve, String template, String output, XMLModel model) throws Exception {
		VelocityContext context = getContext(null, null);
        context.put("model", model);
		File parentPatch = new File(output).getParentFile();
		if (!parentPatch.exists()) {
			parentPatch.mkdirs();
		}
		FileWriter listout = new FileWriter(new File(output));
		String encoding = "utf-8";
		ve.mergeTemplate(template, encoding, context, listout);
		listout.close();
	}

	private static String generateFilename(String rawName) {
		String retFilePath = null;
		StringTokenizer toktok = new StringTokenizer(rawName.replaceAll(":", "_"), "/");
		if (toktok.hasMoreTokens()) {
			File retfile = null;
			retfile = new File(toktok.nextToken());
			while (toktok.hasMoreTokens()) {
				retfile = new File(retfile, toktok.nextToken());
			}
			retFilePath = retfile.getPath();
		}
		return retFilePath;
	}

	private static void ensureParentFolders(File newFile) {
		File parent = newFile.getParentFile();
		if (parent != null && !parent.exists()) {
			try {
				parent.mkdirs();
			} catch (Exception e) {
				LOG.log(Level.WARNING, "Could not create parent directory {0}", parent.getAbsolutePath());
			}
		}
	}

	public static void processFileList(VelocityEngine ve, Expression root, String outputRuleFile, XMLModel model) throws Exception {
		File outputFiles = new File(outputRuleFile);
		List<OutputFileListEntry> fl = OutputFileListHandler.readFileListFile(outputFiles);

		for (OutputFileListEntry f : fl) {
			switch (f.getType()) {
				case PATH:
					break;
				case FILE:
					LOG.log(Level.INFO, "Processing line {0}: Generating file {1}\n", new Object[]{f.getLineNumber(), generateFilename(f.getAttribute("path"))});
					String odfContextStr = f.getAttribute("context");
					String param = f.getAttribute("param");
					VelocityContext context = getContext(odfContextStr, param);
					if (context == null) {
						throw new RuntimeException("Error in output-files.xml, line " + f.getLineNumber() + ": no or invalid odf-scope");
					}else{
                        context.put("model", model);
                    }

					File out = new File(outputRoot + File.separator + generateFilename(f.getAttribute("path"))).getCanonicalFile();
                    LOG.info("Absolute path of generated file: " + out.getAbsolutePath());
					ensureParentFolders(out);
					FileWriter fileout = new FileWriter(out);
					String encoding = "utf-8";

					ve.mergeTemplate(f.getAttribute("template"), encoding, context, fileout);
					fileout.close();
					break;
			}
		}
	}
}
