package imseProc.gmds;

import java.io.File;
import java.util.ArrayList;

import oneLiners.OneLiners;
import org.apache.commons.lang3.StringEscapeUtils;
import org.eclipse.swt.widgets.Composite;
import descriptors.gmds.GMDSSignalDesc;
import otherSupport.SettingsManager;
import signals.Signal;
import signals.gmds.GMDSSignal;
import mds.GMDSFetcher;
import mds.MdsPlusException;
import imseProc.core.IMSEProc;
import imseProc.core.ImagePipeController;
import imseProc.core.ImgPipe;

public abstract class GMDSPipe extends ImgPipe {
	public final static String notesPath = "notes";
	protected GMDSFetcher gmds;
	
	protected int pulse;
	protected String experiment;
	protected String path;
			
	public GMDSPipe() {
		this(IMSEProc.globalGMDS());
	}

	public GMDSPipe(GMDSFetcher gmds) {
		this.gmds = gmds;
		gmds.setUseMemoryCache(false); //we generally don't want this on
	}	
	
	public String getDefaultExperiment(){
		return SettingsManager.defaultGlobal().getProperty("imseProc.cis.experiment", "DEFAULT");
	}

	public int getDefaultPulse(){
		return Integer.parseInt(SettingsManager.defaultGlobal().getProperty("imseProc.cis.pulse", "0"));
	}
	
	public String getDefaultPath(){
		return SettingsManager.defaultGlobal().getProperty("imseProc.cis.path", "RAW/IMAGE");
	}
	
	public String getExperiment(){ return experiment;	}
	public int getPulse(){ return pulse; }
	public String getPath(){ return path; }
	
	@Override
	public ImagePipeController createPipeController(Class interfacingClass, Object args[], boolean asSink) {
		ImagePipeController controller = null;
		if(interfacingClass == Composite.class){
			controller = new GMDSPipeSWTControl((Composite)args[0], (Integer)args[1], this);
			controllers.add(controller);			
		}
		return controller;
	}
	
	@Override
	public String toString() {
		return getClass().getSimpleName() + "[" + hashCode() + "]: " + experiment + "/" + pulse + "/" + path +"]";
	}
	
	public abstract int[] getLoadSaveStatus();
	
	public String getNotes(String experiment, int pulse){
		GMDSSignalDesc notesDesc = new GMDSSignalDesc(pulse, experiment, notesPath);
		try{
			Signal notesSig = gmds.getSig(notesDesc);
			String str = ((String[])notesSig.getData())[0];
			return StringEscapeUtils.unescapeJava(str);
			
		}catch(MdsPlusException err){
			//hack for HDF5-->NetCDF convert
			String fileName = gmds.getCacheRoot() + "/gmds/" + experiment + "/" + pulse + "/notes.txt";
			if( (new File(fileName)).canRead()){
				System.err.println("*** Loaded hacked notes from " + fileName + "***");
				String text = OneLiners.fileToText(fileName);	
				setNotes(experiment, pulse, text);
				return text;
			}
			
			System.err.println("Error reading notes from '"+notesDesc+"': " + err.getMessage());
			return "[EMPTY]";
		}
	}
	
	public void setNotes(String experiment, int pulse, String notes){
		notes = StringEscapeUtils.escapeJava(notes);
		
		GMDSSignalDesc notesDesc = new GMDSSignalDesc(pulse, experiment, notesPath);
		try{
			GMDSSignal notesSig = new GMDSSignal(notesDesc, new String[]{ notes });			
			gmds.writeToCache(notesSig);
			
		}catch(MdsPlusException err){
			System.err.println("Error writing notes to '"+notesDesc+"': " + err.getMessage());
			
		}
	}

	public final static String clearCacheUpdateObj = "clearCacheUpdateObj"; 
	public void setCacheEnable(boolean enable) {
		gmds.setUseMemoryCache(enable);
		if(!enable){
			gmds.clearMemoryCache();
			System.gc(); //once here
			IMSEProc.ensureFinalUpdate(clearCacheUpdateObj, new Runnable() {
				@Override
				public void run() {
					System.gc(); //once again
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) { }
					System.gc(); //god dammit, do it already!
				}
			});
		}
	}
	
	public String[] getAvailableImageSets(String experiment, int pulse){		 
		String paths[] = gmds.dumpCacheTree(experiment, pulse, "/");
		
		//look for anything like and image set (a signal that ends with _COUNT),
		ArrayList<String> imageSets = new ArrayList<String>();
		
		for(String path : paths){
			if(path.endsWith("_COUNT")){
				imageSets.add(path.replaceAll("_COUNT", ""));
			}
		}
		
		return imageSets.toArray(new String[0]);
		
	}
	
	
	public boolean isIdle(){ 
		return !IMSEProc.isUpdateInProgress(this);
	}
}
