/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package pl.edu.pwr.nlptools;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader; 
import java.io.FileWriter; 
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.io.FileUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import pl.edu.pwr.nlpengine.NLPEngineException;

/**
 *
 * @author www_zsk
 */
public class NLPTool {
    private final String serviceName;
    private final String userName="default";
    public final static long MAX_Length=Long.MAX_VALUE;    
    
    private final Client client;
    
    private final String nlptoolURL="http://localhost:8090/";
    private final String dspaceURL="http://156.17.134.56:9220/";
    public final String dspaceNSF="/public-dspace";
    private final String userNSF="/mnt/users";
    
    private final int loglevel=4;

    public NLPTool(String serviceName) {
       this.serviceName=serviceName;
       client=ClientBuilder.newClient();
       
    }
    
    public NLPTool() {
       this.serviceName=null;
       client=ClientBuilder.newClient();
         
    }
    
    public String getNFSPath()
    {
        return "";
    }
    
    
    
    public String booking() throws NLPToolException
    {  String json_i="{\"username\":\""+userName+"\"}";
       String path=null;
       //Timer t=new Timer();
       try 
       {
        
       Response res= client.target(nlptoolURL+"booking").request().post(Entity.entity(json_i, MediaType.APPLICATION_JSON));
       //t.stop("  Booking call");
       
       String ui=res.readEntity(String.class);
       JSONObject resultJSON=new JSONObject(ui);
       path=resultJSON.getString("value");
       //Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "Booking "+path);
       }
       catch (javax.ws.rs.ProcessingException e)
       { Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, e.getMessage());
          throw new NLPToolException("Booking error");
       }
      // t.stop("  Booking result");
        return path;
    }
    
    public  String saveText(String txt) throws  NLPToolException 
    {   String fileID;
        
        fileID=booking();
        //t.stop("Booking");
        if (fileID!=null)
        {
        File file = new File(getNFSPath()+fileID);
        try 
        {
        FileWriter fileWriter = new FileWriter(file);
        try (BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) {
            bufferedWriter.write(txt);   
        }
        }
        catch (IOException ex)
        { Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "file"+fileID, ex.getMessage());
          throw new NLPToolException();
           
        }
        //t.stop("Zaladowanie do NFS");
        }
       /* if (fileID!=null)
        fileID="/mnt/users/default/as/ala.txt"; */
        return fileID;
    }
    
    
    
    
     public  String saveBinary(byte []data) throws  NLPToolException 
    {   String fileID;
        
        fileID=booking();
        
        if (fileID!=null)
        {
        File file = new File(getNFSPath()+fileID);
        try 
        {
        FileOutputStream fileWriter = new FileOutputStream(file);
        
            fileWriter.write(data);   
        
        }
        catch (IOException ex)
        { Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "file"+fileID, ex.getMessage());
          throw new NLPToolException();
           
        }
        
        }
      
        return fileID;
    }
    
     public String saveURL(String url) throws NLPToolException {
        String fileID;
        Date startProcessDate=new Date();
        fileID = booking();
        //System.out.println("Booking " + url+ "time "+  (new Date().getTime() - startProcessDate.getTime()) / 1000.0);
        int maxcount=4;
        int count=maxcount;
            
        if (fileID != null)
            while (count > 0) {
                try {
                    URL website = new URL(url);
                    ReadableByteChannel rbc = Channels.newChannel(website.openStream());
                    FileOutputStream fos = new FileOutputStream(getNFSPath() + fileID);
                    fos.getChannel().transferFrom(rbc, 0, MAX_Length);
                    count = 0;

                } catch (MalformedURLException ex) {
                    Logger.getLogger(NLPTool.class.getName()).log(Level.WARNING, "Wrong URL", ex);
                    throw new NLPToolException("Wrong URL " + url);
                } catch (IOException ex) {
                    Logger.getLogger(NLPTool.class.getName()).log(Level.WARNING, "URL saving problem: " + url + ", attempt " + (maxcount - count + 1), ex.getMessage());
                    count = count - 1;
                    if (count < 0) {
                        throw new NLPToolException("Problems with saving data from: " + url);
                    } else {
                        try {
                            Thread.sleep((int) (Math.random() * 500*((maxcount - count + 1)))+200);
                        } catch (InterruptedException ex1) {
                            Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, null, ex1);
                        }
                    }

                }
            }
      
        return fileID;
    }
    
   
     
     
     public  String saveBinary(InputStream stream) throws  NLPToolException 
    {   String fileID;
        
        fileID=booking();
        
        if (fileID!=null)
        {
        File file = new File(getNFSPath()+fileID);
        try 
        { int read;
          FileOutputStream out = new FileOutputStream(file);
           byte[] bytes = new byte[1024];
           while ((read = stream.read(bytes)) != -1) {
            out.write(bytes, 0, read);
        }
        out.flush();
        out.close();
        
        }
        catch (IOException ex)
        { Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "file"+fileID, ex.getMessage());
          throw new NLPToolException();
           
        }
        
        }
      
        return fileID;
    }
    
     public String getDspaceZipPath(String repo) throws NLPToolException
     {   
        String repo_id,item_id;
        int i=repo.indexOf('/');
        repo_id=repo.substring(0,i-1);
        item_id=repo.substring(i+1);
        if (repo_id !=null && item_id!=null && repo_id.matches("[0-9]+") && repo_id.length() > 2 && item_id.matches("[0-9]+"))
         return  dspaceNSF + "/" + repo+"/wlw_ccl.zip";
        else
          throw new NLPToolException("Wrong dSpace repo ID");  
     }
     //UNUSED ???
     public String readdspacenfs1(String repo) throws NLPToolException {

         
             String dspacePath = getDspaceZipPath(repo);
             String fileID = booking();
      
            try {  File file = new File(getNFSPath() + fileID);
             file.mkdir();
                Charset charset = Charset.forName("CP437");
                ZipInputStream zipIn = new ZipInputStream(new FileInputStream(dspacePath), charset);
                ZipEntry entry = zipIn.getNextEntry();

                // iterates over entries in the zip file
                while (entry != null) {
                    //String filePath = destDirectory + File.separator + entry.getName();
                    if (!entry.isDirectory()) {
                        //String fileID = this.booking();
                String name = entry.getName().replace(File.separator, "%");
                        // if the entry is a file, extracts it
                        extractFile(zipIn, fileID);
                        //fileIDs.add(fileID);
                        //String name = entry.getName().replace(File.separator, "%");
                        name = name + ".txt";
                        //fileNames.add(name);

                    }

                    zipIn.closeEntry();
                    entry = zipIn.getNextEntry();
                }
                zipIn.close();
            } catch (Exception e) {
                //Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "Problems in unziping:" + inputfileID, e);
                throw new NLPToolException("Problems in unziping");
            }
        
   return "";
    }
     
     
      public void unzipFile(String inputfileID, List<String> fileIDs, List<String> fileNames) throws NLPToolException {
        try {
            Charset charset=Charset.forName("CP437");
            //System.out.println(charset.toString());
            
        ZipInputStream zipIn = new ZipInputStream(new FileInputStream(inputfileID),charset);
        ZipEntry entry = zipIn.getNextEntry();
        
        // iterates over entries in the zip file
        while (entry != null) {
            //String filePath = destDirectory + File.separator + entry.getName();
            if (!entry.isDirectory()) {
                String fileID=this.booking();
                //System.out.println("Processing "+entry.getName()+" to "+fileID);
                // if the entry is a file, extracts it
                extractFile(zipIn, fileID);
                fileIDs.add(fileID);
                String name=entry.getName().replace(File.separator,"%");
                name=name+".txt";
                fileNames.add(name);
                
            } 
            
            zipIn.closeEntry();
            entry = zipIn.getNextEntry();
        }
        zipIn.close();
        }
        catch(Exception e)
        {   Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "Problems in unziping:"+inputfileID, e);
            throw new NLPToolException("Problems in unziping");
        }
    }
      
      public void extractFile(ZipInputStream zipIn, String filePath) throws IOException {
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
        byte[] bytesIn = new byte[2048];
        int read = 0;
        while ((read = zipIn.read(bytesIn)) != -1) {
            bos.write(bytesIn, 0, read);
        }
        bos.close();
    }
     
      public String zipFiles(String[] fileIDs,String[] fileNames) throws NLPToolException  {
        String fileID=booking();
        
        if (fileID==null)
        { Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "zip with emtpty list", "");
          throw new NLPToolException();
        }
       
        File file = new File(getNFSPath()+fileID);
        FileOutputStream baos;
        try {
            baos = new FileOutputStream(file);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "Could not open file: "+fileID, ex.getMessage());
            throw new NLPToolException();
        }
        ZipOutputStream zos = new ZipOutputStream(baos);
        byte bytes[] = new byte[2048];
 
        for (int i=0;i<fileIDs.length;i++) {
            String  infile=fileIDs[i];
            String fileName=""+i;
            if (fileNames!=null && fileNames.length>i)
                fileName=fileNames[i];
            FileInputStream fis;
            try {
                //String thePath=URLEncoder.encode(infile, "UTF-8");
                fis = new FileInputStream(getNFSPath()+infile);
                BufferedInputStream bis = new BufferedInputStream(fis);
                zos.putNextEntry(new ZipEntry(fileName));
                int bytesRead;
                while ((bytesRead = bis.read(bytes)) != -1) {
                    zos.write(bytes, 0, bytesRead);}
                zos.closeEntry();
                bis.close();
                fis.close();
            } catch (FileNotFoundException ex) {
                Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "Could not open file:"+fileID, ex.getMessage());
            } catch (IOException ex) {
                Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, null, ex);
            }
                  
        }
        try {
            zos.flush();
            baos.flush();
            zos.close();
            baos.close();
        } catch (IOException ex) {
            Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "Problems with closing files during zip creation", ex.getMessage());
        }
        
 
        
        return fileID;
    } 
     
    public String dirFiles(String[] fileIDs,String[] fileNames) throws NLPToolException  {
        String fileID=booking();
        
        if (fileID==null)
        { Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "dir with emtpty list", "");
          throw new NLPToolException();
        }
       
        File file = new File(getNFSPath()+fileID);
        
        file.mkdir();
        
        
        
        
        for (int i=0;i<fileIDs.length;i++) {
            String  infile=fileIDs[i];
            String fileName=""+i;
            if (fileNames!=null && fileNames.length>i)
                fileName=fileNames[i];
            
            try {
                 String thePath=URLEncoder.encode(fileName, "UTF-8");
                
                Files.createSymbolicLink(Paths.get(getNFSPath()+fileID+'/'+thePath),Paths.get(infile));
                
            } catch (FileNotFoundException ex) {
                Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "Could not open file:"+fileID, ex.getMessage());
            } catch (IOException ex) {
                Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, null, ex);
            }
                  
        }
        
        
 
        
        return fileID;
    } 
     
     
     
     public String decrypt1(String t) throws NLPToolException
    {
        try {
            return Encription.decrypt(t);
        } catch (Exception ex) {
            Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "Wrong format of id", ex);
            throw new NLPToolException("Wrong format of file id");
        }
    }

    public String decrypt(String t) throws NLPToolException
    { String id="";
       //System.out.println("Efekt:"+t);
        try {
            BigInteger  y=new BigInteger(t,radix);
         id=new String(y.toByteArray());
        } catch (Exception ex) {
            Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "Wrong format of id", ex);
            throw new NLPToolException("Wrong format of file id");
        }
        return id;
    }
    private static int radix=32;
    public String encrypt(String s)
    { BigInteger  x=new BigInteger(s.getBytes());
      String id=x.toString(radix);
      return id;
    }
    public String encrypt1(String s) throws NLPToolException
       { 
           try {
               return Encription.encrypt(s);
           } catch (Exception ex) {
               Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, null, ex);
               throw new NLPToolException();
           }
         }   
       
    
    public StringBuilder readFile(String fileID) throws NLPToolException  {
        
        StringBuilder st=new StringBuilder();
        File file = new File(getNFSPath()+fileID);
        FileReader fileReader;
        try {
            fileReader = new FileReader(file);
        
        try (BufferedReader bufferedReader = new BufferedReader(fileReader)) {
            String line=null;
            while ((line=bufferedReader.readLine())!=null)
            st.append(line);
        }   catch (IOException ex) {
                Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, null, ex.getMessage());
               throw new NLPToolException();    
            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, fileID +"not found", ex.getMessage());
            throw new NLPToolException();
        }
        return st;
        
    }
    
    public byte[] readFileBinary(String fileID) throws NLPToolException  {
        
        
        
        Path path = Paths.get(getNFSPath()+fileID);
        try {
            return Files.readAllBytes(path);
        } catch (IOException ex) {
            Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, null, ex);
            throw new NLPToolException("Problem with reading file");
        }
       
        
    }
    
    //Czyta pliki z zip-a z  dspace_nfs i zapisuje go na nfs-ie (booking)
    public void getCCLFromDspace(String corpusid,String fileIDs[],String cclNames[]) throws NLPToolException
    {   
    
        
         String resultPath = dspaceNSF + "/" + corpusid+"/wlw_ccl.zip";
          if (Files.notExists(Paths.get(resultPath)))
          {  Logger.getLogger(NLPTool.class.getName()).log(Level.WARNING, "No "+resultPath+" file", "");
           throw new  NLPToolException("Corpus "+corpusid+ " is not processed in DSpace");
          }
            try {  
                Charset charset = Charset.forName("CP437");
                ZipInputStream zipIn = new ZipInputStream(new FileInputStream(resultPath), charset);
                ZipEntry entry = zipIn.getNextEntry();
                
                while (entry != null) 
                {   
                    String name=entry.getName();
                    for (int i=0;i<cclNames.length;i++)
                    {
                    if (entry.getName().equals(cclNames[i])) {
                     String fileID = this.booking();
                     extractFile(zipIn, getNFSPath()+fileID);
                     fileIDs[i]=fileID;
                     break;
                    }
                    }
                    zipIn.closeEntry();
                    entry = zipIn.getNextEntry();
                    
                }
                
                zipIn.close();
            } catch (Exception e) {
                Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "Problems in unziping:" + resultPath, e);
                throw new  NLPToolException("Problems in unziping corpus: "+corpusid+ " from DSpace");
            }
              
          
            
        
        
        
    }
    
    //Czyta plik z zip-a z  dspace_nfs i zapisuje go na nfs-ie (booking)
    public String dspacenfs2booking(String repo_id, String item_id, String cclname)
    {   String fileID ="";
    
        int id=cclname.lastIndexOf('.');
        if (id>0)
            cclname=cclname.substring(0, id);
        cclname=cclname+".ccl";
        if (repo_id.matches("[0-9]+") && repo_id.length() > 2 && item_id.matches("[0-9]+")  )
        { String resultPath = dspaceNSF + "/" + repo_id+"/"+item_id+"/wlw_ccl.zip";
          if (Files.notExists(Paths.get(resultPath)))
           Logger.getLogger(NLPTool.class.getName()).log(Level.WARNING, "No "+resultPath+" file", "");
          else
          { 
            try {  
                Charset charset = Charset.forName("CP437");
                ZipInputStream zipIn = new ZipInputStream(new FileInputStream(resultPath), charset);
                ZipEntry entry = zipIn.getNextEntry();
                
                while (entry != null) 
                {  if (entry.getName().equals(cclname)) {
                     fileID = this.booking();
                     extractFile(zipIn, getNFSPath()+fileID);
                     System.out.println(cclname);
                    }
                    zipIn.closeEntry();
                    entry = zipIn.getNextEntry();
                }
                if (fileID.isEmpty())
                    Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "File "+cclname+" not found in " + resultPath);    
                zipIn.close();
            } catch (Exception e) {
                Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "Problems in unziping:" + resultPath, e.getMessage());
            }
              
          }
            
        }
        
        return fileID;
    }
    
    public void upload2dspacenfs(String fileID, String repo_id, String item_id, String filename) throws NLPToolException {
            
            if (repo_id.matches("[0-9]+") && repo_id.length() > 2 && item_id.matches("[0-9]+")  ) {        
                
            Path p = Paths.get(filename);
            filename = p.getFileName().toString();
            String resultPath = dspaceNSF + "/" + repo_id+"/"+item_id;
            if (Files.notExists(Paths.get(resultPath))) {
                new File(resultPath).mkdirs();
                if (loglevel > 3) {
                    System.out.println("Creating dir" + resultPath);
                }
            }
            try {
                Files.copy(Paths.get(fileID), Paths.get(resultPath+"/"+filename), REPLACE_EXISTING);
                if (loglevel > 3) {
                    System.out.println("File created " + resultPath+"/"+filename);
                }
            } catch (IOException ex) {
                throw new NLPToolException("File error: " + ex.getMessage());
            }
            }
            else
                System.out.println("Wrong parameters: "+repo_id+"|"+item_id+"|");

        
    }
    
    public void upload2dspace(String fileID, String repo_id, String item_id, String filename,String file_description) throws NLPToolException {

        HttpClient httpclient = new HttpClient();

        /*client.getState().setCredentials(
         new AuthScope(host, 8080, "PortalRealm"),
         new UsernamePasswordCredentials(login, password));
         */
        PostMethod method = new PostMethod(dspaceURL + "dspace/add_file_from_post");
        /*
         method.getParams().setParameter(
         HttpMethodParams.RETRY_HANDLER,
         new DefaultHttpMethodRetryHandler(3, false));
         method.getParams().setCookiePolicy(CookiePolicy.RFC_2109);
         */
        try {
            Part[] parts = new Part[]{
                new StringPart("repo_id", repo_id),
                new StringPart("item_id", item_id),
                new StringPart("file_description", file_description),
                new FilePart("file", filename, new File(getNFSPath() + fileID))
            };

            method.setRequestEntity(
                    new MultipartRequestEntity(parts, method.getParams())
            );

            //method.setDoAuthentication(true);

            int statusCode;
Date startProcessDate=new Date();
            statusCode = httpclient.executeMethod(method);
//System.out.println(""+(new Date().getTime()-startProcessDate.getTime())/1000.0);
            String responseBody = new String(method.getResponseBody());

            if (statusCode != HttpStatus.SC_OK) {
                throw new NLPToolException(method.getStatusLine().toString());
            } else {
                System.out.println(responseBody);
            }
        } catch (IOException ex) {
            Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            method.releaseConnection();
        }
    }
  
    
    public void upload2dspace1(String fileID, String repo_id, String item_id, String file_description) throws NLPToolException {
        NLPTool tool1=new NLPTool("any2txt"); 
        NLPTool tool=new NLPTool("wcrft2");
        JSONObject input = new JSONObject();
        input.put("repo_id", repo_id);
        input.put("item_id", item_id);
        input.put("file_description", file_description);
        Path path = Paths.get(getNFSPath() + fileID);
        try {
            //input.put("file", Files.readAllBytes(path));
                fileID=tool1.processFile(fileID);
            fileID=tool.processFile(fileID);
            input.put("file_url", "http://ws.clarin-pl.eu/nlprest/base/download/"+encrypt(fileID));
                 System.out.println(input.toString());
            Response res = client.target(dspaceURL + "dspace/add_file_from_url_json").request().post(Entity.entity(input, MediaType.APPLICATION_JSON));

            String ui = res.readEntity(String.class);
            System.out.println(ui);
            //JSONObject resultJSON = new JSONObject(ui);

            //Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "Booking "+path);
        } catch (javax.ws.rs.ProcessingException e) {
            Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, e.getMessage());
            throw new NLPToolException("Booking error");
        } catch (Exception ex) {
            Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, null, ex);
            throw new NLPToolException("Problem with reading file");
        }

    }


    
    
    public Status check(String id) {
        
        
        JSONObject input=new JSONObject(); 
        input.put("token", id);
       try 
       {
         Response res= client.target(nlptoolURL+"checking").request().post(Entity.entity(input.toString(), MediaType.APPLICATION_JSON));
         String ui=res.readEntity(String.class);
         
         return new Status(ui);
       }
       catch (javax.ws.rs.ProcessingException e)
       { Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, e.getMessage());
           
       }
        
        
       
        return null;
    }

    /**
    Process file (synchronously)
    
    @param id input file ID 
    @return resulting file ID
     @throws pl.edu.pwr.nlptools.NLPToolException
    **/
    public String processFile(String id) throws NLPToolException {
        String taskID;
        taskID=startTask(id);
        return finishTask(taskID);
    }
    
    public String processFile(String id,String options) throws NLPToolException {
        String taskID;
        taskID=startTask(id,options);
        return finishTask(taskID);
    }
    
     /**
    Process text file (synchronously)
    
    @param id input  text file ID 
    @return resulting file ID
    **/
    public String processText(String id) throws NLPToolException {
        String taskID;
        
        if (this.serviceName.equals("wsd") || this.serviceName.equals("chunker") || this.serviceName.equals("liner2") )
        {
            id=new NLPTool("wcrft2").processFile(id);
        }      
        taskID=startTask(id);
        return finishTask(taskID);
    }
    
  
    
    /**
    waits till  task ends (synchronously)
    
    @param taskID task ID 
    @return resulting file ID
    @throws pl.edu.pwr.nlptools.NLPToolException
    **/
    public String finishTask(String taskID) throws NLPToolException
    {
       Status status = check(taskID);
        
       
       boolean first=true;
       int sleeptime=200;
       while (status.isWaiting())
        {   try {
            Thread.sleep(sleeptime);
           } catch (InterruptedException ex) {
               throw new NLPToolException("Stopped");
           }
        Date startProcessDate = new Date();
        
        status = check(taskID);
        //System.out.println("Check " + taskID+ "time "+  (new Date().getTime() - startProcessDate.getTime()) / 1000.0);
            if (sleeptime<3000)
                 sleeptime=sleeptime+200;
            if (status.isError())
                throw new NLPToolException("Tool: "+this.serviceName+" error: "+status.getValue());
            //if (!status.getStatus().equalsIgnoreCase("QUEUE")   && first ) { t2.stop("Kolejkowanie"); first=false;};
            
        }
       
       return status.getValue();
    }
    
    public String startTask(String id) throws NLPToolException {
        
           return startTask(id,"");
        } 
        
    public String startTask(String id,String options) throws NLPToolException {
        
       Timer t=new Timer();  
       JSONArray data=new JSONArray();
       data.put(new JSONObject().put("tool", serviceName));
       JSONArray files=new JSONArray();
       files.put(id);
       data.put(new JSONObject().put("files", files));
       String def_options="{'model':'default'}";
       if (options==null || options.isEmpty()) options=def_options;
       JSONObject opt=new JSONObject(def_options);
       try {
       opt=new JSONObject(options);
       }
       catch (org.json.JSONException e)
       { Logger.getLogger(NLPTool.class.getName()).log(Level.INFO, "Wrong format of options: "+options);
           
       }
       
       
       //data.put(new JSONObject().put("options", new JSONArray().put("test")));
       data.put(new JSONObject().put("options", opt));
       JSONObject input=new JSONObject(); 
       input.put("data", data);
      
       
      
       Response res= client.target(nlptoolURL+"confirmation").request().post(Entity.entity(input.toString(), MediaType.APPLICATION_JSON));
      
       String ui=res.readEntity(String.class);

       
      
        String path=null;
       try 
       {
        JSONObject resultJSON=new JSONObject(ui);
        String status=resultJSON.getString("status");
        if (status.equals("OK"))
        path=resultJSON.getJSONArray("value").getString(0);
        else
          throw new NLPToolException(resultJSON.getJSONArray("value").getString(0));
       }
       catch (JSONException e)
       {  
          Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, "Wrong answer from engine"+ui, e);
          throw new NLPToolException("Internal error.");  
       }
       
        return path;
        
       
    }

   
    
    
    public static void test1() throws IOException, NLPToolException
    {
        String txt1="- Na osiedlu wrze jak w ulu. We wtorek takie pisma dostawali ludzie z Kazimierza, a w środę my. Ludzie są w szoku, bo kilka dni temu, po zawarciu porozumienia z rządem i Katowickim Holdingiem Węglowym, dostaliśmy zapewnienie, że nie ma się czego bać, a tu coś takiego - mówi Zdzisław Staszowski ze społecznego komitetu obrony mieszkań zakładowych należących do kopalni Kazimierz-Juliusz. Staszowski sam jest emerytowanym górnikiem i mieszka przy ul. Obrońców Warszawy. Przypomnijmy, że górnicy z sosnowieckiej kopalni oprócz obrony zakładu, który miał zostać od października zlikwidowany i postulatu wypłaty zaległych wynagrodzeń protestowali też w obronie mieszkań zakładowych. Ludzie bali się, że z powodu długów kopalni wraz z lokatorami zajmie jej komornik. Wygrali, bo kopalnia będzie fedrowała przez kolejne kilkanaście miesięcy, aż do wyczerpania złóż, a 100 mln zł zastrzyku z budżetu miało rozwiązać problem zaległych pensji i zajęcia mieszkań zakładowych.\n" +
"\n" +
"- Widać, że nic to nie dało. Z moich informacji wynika, że takie pisma dostali najemcy wszystkich 1843 mieszkań zakładowych. Lokatorzy są zdezorientowani i nie wiedzą, co robić. Spotkałem się w tej sprawie z panią ze Śląsko-Dąbrowskiej Spółki Mieszkaniowej, która administruje mieszkaniami zakładowymi. Usłyszałem, że na razie powinniśmy przelewać czynsz na konto, które podał w piśmie komornik - dodaje Staszowski.\n" +
"\n"; 
    
       
    for (int i=0;i<10;i++)
    
    {System.out.println("---------------------------------------------------------");
       Timer t1=new Timer();
       Timer t2=new Timer();
       
       NLPTool nlpTool=new NLPTool("wcrft2");
       String txt="Ala ma kota i idzie daleko, a potem wraca i mruga lewym okiem.";
     txt=txt+txt1+txt1+txt1+txt1;
     //txt=txt+txt;
     //txt=txt+txt;
     //txt=txt+txt;
     //txt=txt+txt;
       String id="",taskID="";
       t2.start();
       id = nlpTool.saveText(txt);
       t2.stop("Zaladowanie pliku");
              
       taskID=nlpTool.startTask(id);
       
       t2.stop("Zaladowanie zadania");
       String resultID=nlpTool.finishTask(taskID);
       
       t2.stop("Wykonanie");
       String result = new String(nlpTool.readFile(resultID));
       t2.stop("Pobranie wyniku");
       t1.stop("Calosc");
       
       
       System.out.println("Rozmiar wyniku "+result.length());
   
       
       
}
    }
    
    
    public static  void test2() throws NLPToolException
    {  Timer t1=new Timer();
       Timer t2=new Timer();
        String txt1="Na osiedlu wrze jak w ulu. We wtorek takie pisma dostawali ludzie z Kazimierza, a w środę my. Ludzie są w szoku, bo kilka dni temu, po zawarciu porozumienia z rządem i Katowickim Holdingiem Węglowym, dostaliśmy zapewnienie, że nie ma się czego bać, a tu coś takiego - mówi Zdzisław Staszowski ze społecznego komitetu obrony mieszkań zakładowych należących do kopalni Kazimierz-Juliusz. Staszowski sam jest emerytowanym górnikiem i mieszka przy ul. Obrońców Warszawy. Przypomnijmy, że górnicy z sosnowieckiej kopalni oprócz obrony zakładu, który miał zostać od października zlikwidowany i postulatu wypłaty zaległych wynagrodzeń protestowali też w obronie mieszkań zakładowych. Ludzie bali się, że z powodu długów kopalni wraz z lokatorami zajmie jej komornik. Wygrali, bo kopalnia będzie fedrowała przez kolejne kilkanaście miesięcy, aż do wyczerpania złóż, a 100 mln zł zastrzyku z budżetu miało rozwiązać problem zaległych pensji i zajęcia mieszkań zakładowych.\n" +
                            "\n" +
                        "- Widać, że nic to nie dało. Z moich informacji wynika, że takie pisma dostali najemcy wszystkich 1843 mieszkań zakładowych. Lokatorzy są zdezorientowani i nie wiedzą, co robić. Spotkałem się w tej sprawie z panią ze Śląsko-Dąbrowskiej Spółki Mieszkaniowej, która administruje mieszkaniami zakładowymi. Usłyszałem, że na razie powinniśmy przelewać czynsz na konto, które podał w piśmie komornik - dodaje Staszowski.\n" +
                     "\n"; 
        
      NLPTool tagger=new NLPTool("wcrft2");
      NLPTool nlpTool=new NLPTool("wsd");
      String txt="Ala ma kota i idzie daleko";
      //txt=txt+txt1+txt1+txt1+txt1;
      String id;
      
      id = nlpTool.saveText(txt);
      t2.stop("zaladowanie pliku");
      id=tagger.processFile(id);
      t2.stop("tager");
      id=nlpTool.processFile(id);
      t2.stop("wsd");
      String result = new String(nlpTool.readFile(id));
      t2.stop("Pobranie wyniku");
      System.out.println(result);
      
      t1.stop("Calosc");
    }
    
    public static void main(String [ ] args) throws IOException, NLPToolException
    { 
       test1();
    }

    public List<String>  getUserDirList(String userid, String klasyfikacja) {
       ArrayList<String> list=new ArrayList<>();
       File curDir=new File(this.userNSF+'/'+userid+'/'+klasyfikacja);
       File[] filesList = curDir.listFiles();
       for (File file:filesList)
       if (file.isDirectory())
        list.add(file.getName());
           
       return list;
    }

    public boolean createDir(String userid, String path) {
     File curDir=new File(this.userNSF+'/'+userid+'/'+path);   
     return curDir.mkdir();
    }
    
    
    public String copyData(String userid, String path,String sourceID)  {
     String dir=   this.userNSF+'/'+userid+'/'+path;
     File destDir=new File(dir);   
     destDir.mkdir();
        try {
            System.out.println("Source: "+ sourceID+"   , dest: "+destDir);
            
            FileUtils.copyDirectory(new File(sourceID), destDir);
            
        } catch (IOException ex) {
            Logger.getLogger(NLPTool.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return dir;
     
    }

   

    
   
}
