package org.gcube.application.geoportal.storage;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.time.LocalDateTime;

import org.gcube.application.geoportal.model.Record;
import org.gcube.application.geoportal.model.content.WorkspaceContent;
import org.gcube.application.geoportal.utils.Serialization;
import org.gcube.application.geoportal.utils.Workspace;
import org.gcube.common.storagehub.client.dsl.FileContainer;
import org.gcube.common.storagehub.client.dsl.FolderContainer;
import org.gcube.common.storagehub.client.dsl.StorageHubClient;
import org.gcube.common.storagehub.model.exceptions.StorageHubException;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class WorkspaceManager {

	
	private Record record;
	
	public WorkspaceManager(Record record) {
		this.record=record;
	}
	
	private StorageHubClient sgClient=null;
	private FolderContainer wsBase=null;
	private FolderContainer appBase=null;

	private static final String APP_FOLDER=".GNA_RECORDS";

	private StorageHubClient getSGClient() {
		if(sgClient==null)
			sgClient=Workspace.getClient();
		return sgClient;
	}

	public FolderContainer getApplicationBaseFolder() throws StorageHubException {
		if(appBase==null) {
			StorageHubClient client=getSGClient();
			FolderContainer vre=client.openVREFolder();
			try {
				appBase = vre.openByRelativePath(APP_FOLDER).asFolder();
			}catch(StorageHubException e) {
				log.debug("APP Fodler missing. Initializing..");
				appBase =  vre.newFolder(APP_FOLDER, "Base folder for GNA records");
				appBase.setHidden();
			}
		}
		return appBase;
	}


	public FileContainer getFileById(String id) throws StorageHubException {
		return getSGClient().open(id).asFile();
	}
	
	public FolderContainer getWSBase() throws StorageHubException {		
		if(wsBase==null) {
			log.debug("WSBASE not set");
			if(record.getFolderId()==null) {
				//init folder
				log.debug("Initializing record folder..");
				String creationTime=Serialization.FULL_FORMATTER.format(LocalDateTime.now());
				String folderName=record.getRecordType()+"_"+record.getNome()+"_"+creationTime;
				log.debug("Folder name will be "+folderName);
				wsBase=getApplicationBaseFolder().newFolder(folderName, "Base folder del record "+record.getNome());
				record.setFolderId(wsBase.getId());
			}
			log.debug("Opening folder");
			wsBase=getSGClient().open(record.getFolderId()).asFolder();
		}
		return wsBase;
	}

	public FolderContainer getSubFolder(String path) throws StorageHubException {
		return getSubFolder(getWSBase(),path);
	}
	
	private FolderContainer getSubFolder(FolderContainer parentFolder,String path) throws StorageHubException {		
		try{
			return parentFolder.openByRelativePath(path).asFolder();
		}catch(StorageHubException e) {			
			log.debug("Missing subPath "+path);
			FolderContainer targetParent=parentFolder;
			String targetName=path;
			if(path.contains("/")) {
				String parent=path.substring(0, path.lastIndexOf("/"));
				log.debug("Checking intermediate "+parent);
				targetParent=getSubFolder(parentFolder,parent);
				targetName=path.substring(path.lastIndexOf("/")+1);
			}
			log.debug("Creating "+targetName);
			return targetParent.newFolder(targetName, "");
		}
	}


	public WorkspaceContent storeToWS(File f,FolderContainer destination,String name,String description) throws FileNotFoundException, StorageHubException {
		FileContainer item=destination.uploadFile(new FileInputStream(f), name, description);
		item=getSGClient().open(item.getId()).asFile();

		WorkspaceContent content=new WorkspaceContent();
		content.setLink(item.getPublicLink().toString());
		content.setMimetype(item.get().getContent().getMimeType());

		content.setStorageID(item.getId());
		return content;	

	}
	
	public void deleteFromWS(WorkspaceContent toDelete) throws StorageHubException {
		getSGClient().open(toDelete.getStorageID()).asFile().forceDelete();
	}
}
