/*
 *  Object FIFO buffer with limited capacity services class
 *
 *  2004 - 2011 Frantisek Zboril jr.
 *  Faculty of Information Technology
 *  zborilf@fit.vutbr.cz
 *  http://www.fit.vutbr.cz/~zborilf
 *
 * (C) Brno University of Technology
 * Freeware licence VUT v Brně
 * https://wis.fit.vutbr.cz/FIT/db/dir.php/dr/VZ2007/externiInformace/softwareNaWebu/Priloha2_rozh23.pdf

 */

package jTMass.core.jTMassPlatform.jTServices;

import jTMass.TMass;
import jTMass.core.jALLL.jTObjects.TAtom;
import jTMass.core.jALLL.jTObjects.TFail;
import jTMass.core.jALLL.jTObjects.TList;
import jTMass.core.jALLL.jTObjects.TObject;
import jTMass.core.jTMassPlatform.TPlatform;

public class TSLimitedBuffer extends TASSynchronousService{

    private static final int _Max_Buffer_Size=20;
    // nb, newbuffer (bufname, size) :null / TFail
    // p, put (bufname, object) :null / TFail
    // g, get (bufname) :object

    TObject newBuffer(TObject parameters, TPlatform platform){
        if(parameters instanceof TList)
            if(((TList)parameters).size()==2)
                if(((TList)parameters).get(0) instanceof TAtom)
                    if(((TList)parameters).get(1) instanceof TAtom){
                        String name="~"+((TList)parameters).get(0).getContent();
                        Integer size=Integer.valueOf(((TList)parameters).get(1).getContent());
                        if(size>_Max_Buffer_Size)
                            return(new TFail());
                        TList buffer=new TList();
                        platform.addVariable(name, buffer);
                        name=name+"_size";
                        platform.addVariable(name, new TAtom(size));
                        return(null);
                    }
        return(new TFail());
    }

    TObject putItem(TObject parameters, TPlatform platform){
        if(parameters instanceof TList)
            if(((TList)parameters).size()==2)
                if(((TList)parameters).get(0) instanceof TAtom){
                    String name="~"+((TList)parameters).get(0).getContent();
                    TObject content=platform.getVariable(name);
                    if(!(content instanceof TList))
                        return(new TFail());
                    Integer maxSize=0;
                    
                    try{
                        TObject maxSizeO=platform.getVariable(name+"_size");
                        maxSize=Integer.valueOf(maxSizeO.getContent());
                    }catch(Exception e){
                        TMass._Terminal.reportError("Wrong buffer size variable format");
                        return(new TFail());
                    }

                    if(((TList)content).size()==maxSize)
                            return(new TFail());

                    if(((TList)parameters).get(1) instanceof TList){

                        if(((TList)((TList)parameters).get(1)).size()+
                                ((TList)content).size()>maxSize)
                            return(new TFail());
                        for(int i=0;i<((TList)((TList)parameters).get(1)).size();i++)
                            ((TList)content).addFirst(((TList)((TList)parameters).get(1)).get(i));
                    }
                    else
                        ((TList)content).addFirst(((TList)parameters).get(1));
                    platform.addVariable(name, content);
                    return(null);
                }
        return(new TFail());
    }

    TObject getItem(TObject parameters, TPlatform platform){
        if(parameters instanceof TList)
            if(((TList)parameters).size()==1)
                if(((TList)parameters).get(0) instanceof TAtom){
                    String name="~"+((TList)parameters).get(0).getContent();
                    TObject content=platform.getVariable(name);
                    if(!(content instanceof TList))
                        return(new TFail());

                    if(((TList)content).isEmpty())
                        return(new TFail());
                    
                    TObject result=((TList)content).popFirst();
                    platform.refreshVRPanel();
                    return(result);
                }
        return(new TFail());
    }

    @Override
    public TObject processService(TList parameters, String clientName, String serviceName){
        super.processService(parameters,clientName,serviceName);
        if(parameters.size()==2)
            if(parameters.get(0) instanceof TAtom){
                String op=parameters.get(0).getContent();
                if(op.contentEquals("nb"))
                    return(newBuffer(parameters.get(1),PPlatform));
                if(op.contentEquals("p")){
                    return(putItem(parameters.get(1),PPlatform));
                }
                if(op.contentEquals("g")){
                   return(getItem(parameters.get(1),PPlatform));
                }
            }   

        return(new TFail());
    }

    public TSLimitedBuffer(TPlatform platform){
        super(platform);
    }

}