/*****************************************************************************
 * 
 * Copyright (c) 2016 CEA LIST.
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *  CEA LIST Initial API and implementation
 * 
 *****************************************************************************/
package org.eclipse.papyrus.moka.fmi.fmu;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.eclipse.emf.ecore.util.BasicExtendedMetaData;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl;
import org.eclipse.papyrus.moka.fmi.fmumetamodel.AbstractFile;
import org.eclipse.papyrus.moka.fmi.fmumetamodel.ArchiveToUnzipInFMU;
import org.eclipse.papyrus.moka.fmi.fmumetamodel.FMUBundle;
import org.eclipse.papyrus.moka.fmi.fmumetamodel.FmumetamodelFactory;
import org.eclipse.papyrus.moka.fmi.fmumetamodel.FolderToCreateInFMU;
import org.eclipse.papyrus.moka.fmi.fmumetamodel.JavaFileProxy;
import org.eclipse.papyrus.moka.fmi.modeldescription.DocumentRoot;
import org.eclipse.papyrus.moka.fmi.modeldescription.FmiFactory;
import org.eclipse.papyrus.moka.fmi.modeldescription.FmiModelDescriptionType;
import org.eclipse.papyrus.moka.fmi.modeldescription.FmiPackage;
import org.eclipse.papyrus.moka.fmi.modeldescription.util.FmiResourceImpl;
import org.eclipse.papyrus.moka.fmi.util.FMUResourceUtil;
import org.eclipse.papyrus.moka.fmi.util.UnzipUtility;

public class FMUResource extends XMLResourceImpl {

	FMUParser fmuParser;
	FMUBundle fmuBundle;

	public FMUParser getFmuParser() {
		return fmuParser;
	}

	@Override
	public void doLoad(InputStream inputStream, Map<?, ?> options) throws IOException {

		Path tmpDirectoryPath = Files.createTempDirectory("fmuResource");
		UnzipUtility.unzip(new ZipInputStream(inputStream), tmpDirectoryPath.toString(), uri.lastSegment());
		fmuParser = new FMUParser(tmpDirectoryPath.toString());
		createFmuBundle();
		getContents().add(fmuBundle);

	}

	private void createFmuBundle() throws IOException {
		fmuBundle = FmumetamodelFactory.eINSTANCE.createFMUBundle();
		if (fmuParser.getModelDescription() != null) {
			fmuBundle.setModelDescription(fmuParser.getModelDescription());
		}

		File fmuFolder = fmuParser.getFMUFolder();
		for (File fmuChildFile : fmuFolder.listFiles()) {
			switch (fmuChildFile.getName()) {
			case FMUResourceUtil.FOLDER_RESOURCES:
				fmuBundle.getResourcesFiles().addAll(FMUResourceUtil.createJavaFileProxies(fmuChildFile.listFiles()));
				break;

			case FMUResourceUtil.FOLDER_DOCUMENTATION:
				fmuBundle.getDocumentationFiles()
						.addAll(FMUResourceUtil.createJavaFileProxies(fmuChildFile.listFiles()));
				break;

			case FMUResourceUtil.FOLDER_SOURCES:
				fmuBundle.getSourceFiles()
						.addAll(FMUResourceUtil.createJavaFileProxies(fmuChildFile.listFiles()));
				break;

			case FMUResourceUtil.FOLDER_BINARIES:
				for (File fmuGrandChildFile : fmuChildFile.listFiles()) {
					switch (fmuGrandChildFile.getName()) {
					case FMUResourceUtil.BINARIES_WIN32:
						fmuBundle.getWin32Files()
								.addAll(FMUResourceUtil.createJavaFileProxies(fmuGrandChildFile.listFiles()));
						break;
					case FMUResourceUtil.BINARIES_WIN64:
						fmuBundle.getWin64Files()
								.addAll(FMUResourceUtil.createJavaFileProxies(fmuGrandChildFile.listFiles()));
						break;
					case FMUResourceUtil.BINARIES_LINUX32:
						fmuBundle.getLinux32Files()
								.addAll(FMUResourceUtil.createJavaFileProxies(fmuGrandChildFile.listFiles()));
						break;
					case FMUResourceUtil.BINARIES_LINUX64:
						fmuBundle.getLinux64Files()
								.addAll(FMUResourceUtil.createJavaFileProxies(fmuGrandChildFile.listFiles()));
						break;
					case FMUResourceUtil.BINARIES_DARWIN32:
						fmuBundle.getDarwin32Files()
								.addAll(FMUResourceUtil.createJavaFileProxies(fmuGrandChildFile.listFiles()));
						break;
					case FMUResourceUtil.BINARIES_DARWIN64:
						fmuBundle.getDarwin64Files()
								.addAll(FMUResourceUtil.createJavaFileProxies(fmuGrandChildFile.listFiles()));
						break;

					default:
						// there should not be a file there, but we keep track
						// of it as a root file with a compound path
						fmuBundle.getRootFiles().add(FMUResourceUtil.createJavaFileProxy(fmuGrandChildFile,
								FMUResourceUtil.FOLDER_BINARIES + "/" + fmuGrandChildFile.getName()));
						break;
					}
				}

			default:
				if (! FMUResourceUtil.isAStandardFile(fmuChildFile)){
					fmuBundle.getRootFiles().add(FMUResourceUtil.createJavaFileProxy(fmuChildFile));
				}
			
				break;
			}

		}

	}

	@Override
	public void doSave(OutputStream outputStream, Map<?, ?> options) throws IOException {
		if (getContents().get(0) instanceof FMUBundle) {
			fmuBundle = (FMUBundle) getContents().get(0);
			ZipOutputStream zipOputputStream = new ZipOutputStream(outputStream);

			saveModelDescription(zipOputputStream);
			saveBinaries(zipOputputStream);
			saveResources(zipOputputStream);
			saveSources(zipOputputStream);
			saveDocumentation(zipOputputStream);
			saveRoot(zipOputputStream);
			zipOputputStream.close();

		} else {
			throw new IOException("The content of the FMUResource should be a FMUBundle");
		}

	}

	private void saveModelDescription(ZipOutputStream zipOutputStream) throws IOException {
		if (fmuBundle.getModelDescription() != null) {

			XMLResource modelDescRes = new FmiResourceImpl(null);
			FmiModelDescriptionType modelDesc = EcoreUtil.copy(fmuBundle.getModelDescription());
			DocumentRoot root = FmiFactory.eINSTANCE.createDocumentRoot();
			root.setFmiModelDescription(modelDesc);
			modelDescRes.getContents().add(root);
			ExtendedMetaData exMet = new BasicExtendedMetaData();
			exMet.setQualified(FmiPackage.eINSTANCE, false);
			Map<Object, Object> saveOptions = new HashMap<Object, Object>();
			saveOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, exMet);
			saveOptions.put(XMLResource.OPTION_ENCODING, "utf-8");

			StringWriter stringWriter = new StringWriter();
			modelDescRes.save(stringWriter, saveOptions);

			ZipEntry modelDescEntry = new ZipEntry(FMUResourceUtil.MODEL_DESCRIPTION_FILE_NAME);
			zipOutputStream.putNextEntry(modelDescEntry);
			zipOutputStream.write(stringWriter.getBuffer().toString().getBytes());
			zipOutputStream.closeEntry();

		}

	}

	private void saveBinaries(ZipOutputStream zipOputputStream) throws IOException {
		addFiles(fmuBundle.getWin32Files(), zipOputputStream,
				FMUResourceUtil.FOLDER_BINARIES + "/" + FMUResourceUtil.BINARIES_WIN32);
		addFiles(fmuBundle.getWin64Files(), zipOputputStream,
				FMUResourceUtil.FOLDER_BINARIES + "/" + FMUResourceUtil.BINARIES_WIN64);
		addFiles(fmuBundle.getLinux32Files(), zipOputputStream,
				FMUResourceUtil.FOLDER_BINARIES + "/" + FMUResourceUtil.BINARIES_LINUX32);
		addFiles(fmuBundle.getLinux64Files(), zipOputputStream,
				FMUResourceUtil.FOLDER_BINARIES + "/" + FMUResourceUtil.BINARIES_LINUX64);
		addFiles(fmuBundle.getDarwin32Files(), zipOputputStream,
				FMUResourceUtil.FOLDER_BINARIES + "/" + FMUResourceUtil.BINARIES_DARWIN32);
		addFiles(fmuBundle.getDarwin64Files(), zipOputputStream,
				FMUResourceUtil.FOLDER_BINARIES + "/" + FMUResourceUtil.BINARIES_DARWIN64);
	}

	private void saveRoot(ZipOutputStream zipOutputStream) throws IOException {
		addFiles(fmuBundle.getRootFiles(), zipOutputStream, ".");
	}

	private void saveDocumentation(ZipOutputStream zipOutputStream) throws IOException {
		addFiles(fmuBundle.getDocumentationFiles(), zipOutputStream,FMUResourceUtil.FOLDER_DOCUMENTATION );
	}

	private void saveResources(ZipOutputStream zipOutputStream) throws IOException {
		addFiles(fmuBundle.getResourcesFiles(), zipOutputStream, FMUResourceUtil.FOLDER_RESOURCES);
	}
	
	private void saveSources(ZipOutputStream zipOutputStream) throws IOException {
		addFiles(fmuBundle.getSourceFiles(), zipOutputStream, FMUResourceUtil.FOLDER_SOURCES);
	}

	private void addFile(AbstractFile fmuFile, ZipOutputStream zipOutputStream, String fmuFolder) throws IOException {
		if (fmuFile instanceof JavaFileProxy && ((JavaFileProxy) fmuFile).getFile() != null
				&& ((JavaFileProxy) fmuFile).getFile().exists()) {
			addEntry(((JavaFileProxy) fmuFile).getFile(), zipOutputStream, fmuFolder, fmuFile.getName());

		} else if (fmuFile instanceof FolderToCreateInFMU) {
			FolderToCreateInFMU folderToCreate = (FolderToCreateInFMU) fmuFile;

			if (folderToCreate.getChildren().isEmpty()) {
				createEmptyDir(zipOutputStream, fmuFolder + "/" + folderToCreate.getName());
			} else {
				for (AbstractFile childFile : folderToCreate.getChildren()) {
					addFile(childFile, zipOutputStream, fmuFolder + "/" + folderToCreate.getName());
				}
			}

		} else if (fmuFile instanceof ArchiveToUnzipInFMU) {
			unzipArchiveFile((ArchiveToUnzipInFMU) fmuFile, zipOutputStream, fmuFolder);
		}

	}

	private void addFiles(List<AbstractFile> fmuFiles, ZipOutputStream zipOutputStream, String fmuFolder)
			throws IOException {
		for (AbstractFile fmuFile : fmuFiles) {
			addFile(fmuFile, zipOutputStream, fmuFolder);
		}
	}

	private void unzipArchiveFile(ArchiveToUnzipInFMU archiveToAdd, ZipOutputStream zipOutputStream, String fmuFolder)
			throws IOException {
		if (archiveToAdd.getArchiveFile() != null && archiveToAdd.getArchiveFile().exists()) {
			String rootName = fmuFolder;
			try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(archiveToAdd.getArchiveFile()));) {

				if (archiveToAdd.getName() != null) {
					rootName = fmuFolder +"/"+ archiveToAdd.getName();
				}

				ZipEntry entryToCopy;
				while ((entryToCopy = zipIn.getNextEntry()) != null) {
					ZipEntry newEntry = new ZipEntry(rootName + "/" + entryToCopy.getName());
					zipOutputStream.putNextEntry(newEntry);
					byte[] buffer = new byte[1024];
					int len;
					while ((len = zipIn.read(buffer)) > 0) {
						zipOutputStream.write(buffer, 0, len);
					}
					zipOutputStream.closeEntry();
				}
			}
			;

		}

	}

	private void createEmptyDir(ZipOutputStream zipOutputStream, String entryName) throws IOException {
		ZipEntry emptyDirEntry = new ZipEntry(entryName + "/");
		zipOutputStream.putNextEntry(emptyDirEntry);
		zipOutputStream.closeEntry();
	}

	private void addEntry(File file, ZipOutputStream zipOutputStream, String fmuFolder, String entryName)
			throws IOException {
		String name = entryName != null ? entryName : file.getName();
		if (file.isDirectory()) {
			if (file.listFiles().length == 0) {
				createEmptyDir(zipOutputStream, fmuFolder + "/" + name);
			}
			for (File child : file.listFiles()) {
				addEntry(child, zipOutputStream, fmuFolder + "/" + name, null);
			}
		} else {
			ZipEntry fileEntry = new ZipEntry(fmuFolder + "/" + name);
			try (FileInputStream in = new FileInputStream(file)) {
				zipOutputStream.putNextEntry(fileEntry);
				byte[] buffer = new byte[1024];
				int len;
				while ((len = in.read(buffer)) > 0) {
					zipOutputStream.write(buffer, 0, len);
				}
				zipOutputStream.closeEntry();
			}
		}
	}

	@Override
	protected void doUnload() {
		super.doUnload();
		if (fmuParser != null) {
			fmuParser.clean();
			fmuParser = null;
		}

	}
}