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.");
	}
}
