/*******************************************************************************
 * Copyright (C) 2021 the Eclipse BaSyx Authors
 * 
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 * 
 * SPDX-License-Identifier: EPL-2.0
 ******************************************************************************/
package org.eclipse.basyx.aas.factory.aasx;

import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.UUID;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.stream.StreamResult;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.RelationshipSource;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.openxml4j.opc.internal.MemoryPackagePart;
import org.eclipse.basyx.aas.factory.xml.MetamodelToXMLConverter;
import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
import org.eclipse.basyx.aas.metamodel.api.parts.asset.IAsset;
import org.eclipse.basyx.submodel.metamodel.api.ISubModel;
import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElement;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
import org.eclipse.basyx.vab.exception.provider.ResourceNotFoundException;
import org.eclipse.basyx.vab.modelprovider.VABPathTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * This class can be used to generate an .aasx file from
 * Metamodel Objects and the Files referred to in the Submodels
 * 
 * @author conradi
 *
 */
public class AASXFactory {
	
	private static Logger logger = LoggerFactory.getLogger(AASXFactory.class);
	
	private static final String MIME_PLAINTXT = "text/plain";
	private static final String MIME_XML = "application/xml";

	private static final String ORIGIN_RELTYPE = "http://www.admin-shell.io/aasx/relationships/aasx-origin";
	private static final String ORIGIN_PATH = "/aasx/aasx-origin";
	private static final String ORIGIN_CONTENT = "Intentionally empty.";
	
	
	private static final String AASSPEC_RELTYPE = "http://www.admin-shell.io/aasx/relationships/aas-spec";
	private static final String XML_PATH = "/aasx/xml/content.xml";
	
	
	private static final String AASSUPPL_RELTYPE = "http://www.admin-shell.io/aasx/relationships/aas-suppl";
	
	
	
	/**
	 * Generates the .aasx file and writes it to the given OutputStream
	 * 
	 * @param aasList the AASs to be saved in the .aasx
	 * @param assetList the Assets to be saved in the .aasx
	 * @param conceptDescriptionList the ConceptDescriptions to be saved in the .aasx
	 * @param submodelList the Submodels to be saved in the .aasx
	 * @param files the files referred to in the Submodels
	 * @param os the OutputStream the resulting .aasx is written to
	 * @throws IOException
	 * @throws TransformerException
	 * @throws ParserConfigurationException
	 */
	public static void buildAASX(Collection<IAssetAdministrationShell> aasList, Collection<IAsset> assetList, 
			Collection<IConceptDescription> conceptDescriptionList, Collection<ISubModel> submodelList, Collection<InMemoryFile> files, OutputStream os) throws IOException, TransformerException, ParserConfigurationException {
		
		prepareFilePaths(submodelList);
		
		OPCPackage rootPackage = OPCPackage.create(os);
		
		// Create the empty aasx-origin file
		PackagePart origin = createAASXPart(rootPackage, rootPackage, ORIGIN_PATH, MIME_PLAINTXT, ORIGIN_RELTYPE, ORIGIN_CONTENT.getBytes());
		
		// Convert the given Metamodels to XML
		String xml = convertToXML(aasList, assetList, conceptDescriptionList, submodelList);
		
		// Save the XML to aasx/xml/content.xml
		PackagePart xmlPart = createAASXPart(rootPackage, origin, XML_PATH, MIME_XML, AASSPEC_RELTYPE, xml.getBytes());
		
		storeFilesInAASX(submodelList, files, rootPackage, xmlPart);
		
		saveAASX(os, rootPackage);
	}

	/**
	 * Stores the files from the Submodels in the .aasx file
	 * 
	 * @param submodelList the Submodels
	 * @param files the content of the files
	 * @param rootPackage the OPCPackage
	 * @param xmlPart the Part the files should be related to
	 */
	private static void storeFilesInAASX(Collection<ISubModel> submodelList, Collection<InMemoryFile> files,
			OPCPackage rootPackage, PackagePart xmlPart) {
		
		for(ISubModel sm: submodelList) {
			for(File file: findFileElements(sm.getSubmodelElements().values())) {
				String filePath = file.getValue();
				try {
					InMemoryFile content = findFileByPath(files, filePath);
					logger.trace("Writing file '" + filePath + "' to .aasx.");
					createAASXPart(rootPackage, xmlPart, filePath, file.getMimeType(), AASSUPPL_RELTYPE, content.getFileContent());
				} catch (ResourceNotFoundException e) {
					// Log that a file is missing and continue building the .aasx
					logger.warn("Could not add File '" + filePath + "'. It was not contained in given InMemoryFiles.");
				}
			}
		}
	}
	
	/**
	 * Saves the OPCPackage to the given OutputStream
	 * 
	 * @param os the Stream to be saved to
	 * @param rootPackage the Package to be saved
	 * @throws IOException
	 */
	private static void saveAASX(OutputStream os, OPCPackage rootPackage) throws IOException {
		rootPackage.flush();
		rootPackage.save(os);
	}
	
	/**
	 * Generates a UUID. Every element of the 
	 * .aasx needs a unique Id according to the specification
	 * 
	 * @return UUID
	 */
	private static String createUniqueID() {
		return UUID.randomUUID().toString();
	}
	
	/**
	 * Creates a Part (a file in the .aasx) of the .aasx and adds it to the Package
	 * 
	 * @param root the OPCPackage
	 * @param relateTo the Part of the OPC the relationship of the new Part should be added to
	 * @param path the path inside the .aasx where the new Part should be created
	 * @param mimeType the mime-type of the file
	 * @param relType the type of the Relationship
	 * @param content the data the new part should contain
	 * @return the created PackagePart; Returned in case it is needed late as a Part to relate to
	 */
	private static PackagePart createAASXPart(OPCPackage root, RelationshipSource relateTo, String path, String mimeType, String relType, byte[] content) {
		if(mimeType == null || mimeType.equals("")) {
			throw new RuntimeException("Could not create AASX Part '" + path + "'. No MIME_TYPE specified.");
		}
		
		PackagePartName partName = null;
		MemoryPackagePart part = null;
		try {
			partName = PackagingURIHelper.createPartName(path);
			part = new MemoryPackagePart(root, partName, mimeType);
		} catch (InvalidFormatException e) {
			// This occurs if the given MIME-Type is not valid according to RFC2046
			throw new RuntimeException("Could not create AASX Part '" + path + "'", e);
		}		
		writeDataToPart(part, content);
		root.registerPartAndContentType(part);
		relateTo.addRelationship(partName, TargetMode.INTERNAL, relType, createUniqueID());
		return part;
	}
	
	/**
	 * Writes the content of a byte[] to a Part
	 * 
	 * @param part the Part to be written to
	 * @param content the content to be written to the part
	 */
	private static void writeDataToPart(PackagePart part, byte[] content) {
		try(OutputStream ostream = part.getOutputStream();) {
			ostream.write(content);
			ostream.flush();
		} catch (Exception e) {
			throw new RuntimeException("Failed to write content to AASX Part '" + part.getPartName().getName() + "'", e);
		}
	}
	
	/**
	 * Uses the MetamodelToXMLConverter to generate the XML
	 */
	private static String convertToXML(Collection<IAssetAdministrationShell> aasList, Collection<IAsset> assetList, 
			Collection<IConceptDescription> conceptDescriptionList, Collection<ISubModel> submodelList) throws TransformerException, ParserConfigurationException {
		
		StringWriter writer = new StringWriter();
		MetamodelToXMLConverter.convertToXML(aasList, assetList, conceptDescriptionList, submodelList, new StreamResult(writer));
		
		return writer.toString();
	}
	
	/**
	 * Gets the File elements from a collection of elements
	 * Also recursively searches in SubmodelElementCollections
	 * 
	 * @param elements the Elements to be searched for File elements
	 * @return the found Files
	 */
	private static Collection<File> findFileElements(Collection<ISubmodelElement> elements) {		
		Collection<File> files = new ArrayList<>();
		
		for(ISubmodelElement element: elements) {
			if(element instanceof File) {
				files.add((File) element);
			} else if(element instanceof SubmodelElementCollection) {
				// Recursive call to deal with SubmodelElementCollections
				files.addAll(findFileElements(((SubmodelElementCollection) element).getSubmodelElements().values()));
			}
		}
		
		return files;
	}
	
	/**
	 * Replaces the path in all File Elements with the result of preparePath
	 * 
	 * @param submodels the Submodels
	 */
	private static void prepareFilePaths(Collection<ISubModel> submodels) {
		submodels.stream()
			.forEach(sm -> findFileElements(sm.getSubmodelElements().values()).stream().forEach(f -> f.setValue(preparePath(f.getValue()))));
	}
	
	/**
	 * Removes the serverpart from a path and ensures it starts with a slash
	 * 
	 * @param path the path to be prepared
	 * @return the prepared path
	 */
	private static String preparePath(String path) {
		String newPath = VABPathTools.getPathFromURL(path);
		if(!newPath.startsWith("/")) {
			newPath = "/" + newPath;
		}
		return newPath;
	}
	
	/**
	 * Finds an InMemoryFile by its path
	 * 
	 * @param files the InMemoryFiles
	 * @param path the path of the wanted file
	 * @return the InMemoryFile if it was found; else null
	 */
	private static InMemoryFile findFileByPath(Collection<InMemoryFile> files, String path) {
		for(InMemoryFile file: files) {
			if(preparePath(file.getPath()).equals(path)) {
				return file;
			}
		}
		throw new ResourceNotFoundException("The wanted file '" + path + "' was not found in the given files.");
	}
}
