/*
 * 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.any2txt;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
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.io.FileUtils;
import org.apache.tika.Tika;
import org.apache.tika.detect.AutoDetectReader;
import org.apache.tika.exception.TikaException;
import org.apache.tika.io.TikaInputStream;
import org.apache.tika.metadata.Metadata;
import org.json.JSONException;
import org.json.JSONObject;

/**
 *
 * @author www_zsk
 */
public class Converter extends Thread{
     public static void main(String[] args) {
           tool();        
        //test();
    }
    private final String outfilename;
    private final String filename;
    private final boolean del;
  static private Semaphore semaphore;
  
   public Converter(String filename, String outfilename,boolean  del) {
         this.filename=filename;
         this.del=del;
         this.outfilename=outfilename;
     

    }
    public static void tool() {
       
        IniFile init;
        try {
            init = new IniFile("config.ini");
            String toolname = init.getString("path", "tool", "error");
            Logger.getLogger(Converter.class.getName()).log(Level.INFO, "Starting tool: " + toolname);
            Integer workers_number=Integer.parseInt(init.getString("options", "workers_number", "8"));
            String url = init.getString("path", "url", "error");
            String root = init.getString("path", "root", "error");
            String process = root + toolname + "/" + init.getString("path", "process", "error");
            String done = root + toolname + "/" + init.getString("path", "done", "error");
            String json_i = "{\"tool\":\"" + toolname + "\"}";
            Client client = ClientBuilder.newClient();
            String ui="";
             semaphore= new Semaphore(workers_number);
            
            Logger.getLogger(Converter.class.getName()).log(Level.INFO, toolname + " started with url: "+url+ " and " + workers_number +" workers !");
            while (true) {
                try {
                Response res = client.target(url).request().post(Entity.entity(json_i, MediaType.APPLICATION_JSON));
                ui = res.readEntity(String.class);
                JSONObject resultJSON = new JSONObject(ui);
                String fileid = resultJSON.getString("task");
                if (fileid.isEmpty()) {
                    Thread.sleep(200);
                    continue;
                }
                
                
                
                processFile(process + fileid, done + fileid, true);
                
            }
            catch (JSONException ex)
            {
                 Logger.getLogger(Converter.class.getName()).log(Level.WARNING, "Wrong request from Tasker", ui);
                 Thread.sleep(10000);
            }
            catch (Exception ex)
            {
                 Logger.getLogger(Converter.class.getName()).log(Level.WARNING, "Problems with connection to Tasker", ex.getMessage());
                 Thread.sleep(10000);
            }
                
            }

        } catch (IOException | InterruptedException ex) {
            Logger.getLogger(Converter.class.getName()).log(Level.SEVERE, "any2txt stoped!", ex);
        }

    }

    public static void test()  {
        System.out.println("Testing!");
        semaphore= new Semaphore(8);
         try {
           /*  tprocessFile("/home/www_zsk/any2txt_test/in/1.txt", "/home/www_zsk/any2txt_test/out/1.txt", false);
             tprocessFile("/home/www_zsk/any2txt_test/in/2.txt", "/home/www_zsk/any2txt_test/out/2.txt", false);
        tprocessFile("/home/www_zsk/any2txt_test/in/3.txt", "/home/www_zsk/any2txt_test/out/3.txt", false);
        tprocessFile("/home/www_zsk/A25.odt","/home/www_zsk/any2txt_test/out/0.1.txt" ,false);
        tprocessFile("/home/www_zsk/test.docx","/home/www_zsk/any2txt_test/out/test.txt" ,false);
        tprocessFile("/home/www_zsk/test11","/home/www_zsk/any2txt_test/out/test1.txt",false);
        tprocessFile("/home/www_zsk/test2","/home/www_zsk/any2txt_test/out/test2.txt",false);
        tprocessFile("/home/www_zsk/as.txt","/home/www_zsk/any2txt_test/out/test3.txt",false);
        tprocessFile("/home/www_zsk/test.xlsx","/home/www_zsk/any2txt_test/out/test4.txt",false);
        tprocessFile("/home/www_zsk/Architektura.rtf","/home/www_zsk/any2txt_test/out/test5.txt",false); */
        tprocessFile("/home/www_zsk/any2txt_test/in/4.txt","/home/www_zsk/any2txt_test/out/test4_n.txt",false); 
        tprocessFile("/home/www_zsk/test5.txt","/home/www_zsk/any2txt_test/out/test6.txt",false);
        tprocessFile("/home/www_zsk/any2txt_test/in/160.txt","/home/www_zsk/any2txt_test/out/test8.txt",false);
         
         
         } catch (InterruptedException ex) {
             Logger.getLogger(Converter.class.getName()).log(Level.SEVERE, null, ex);
         }
        
        System.out.println("Finihed!");
    }

    
    public static void tprocessFile(String filename, String outfilename,boolean del) throws InterruptedException {
        //   Files.copy(Paths.get(filename),Paths.get(tmp),StandardCopyOption.REPLACE_EXISTING);
              processFile(filename, outfilename,del);
       
     }
     public static void processFile(String filename, String outfilename,boolean del) throws InterruptedException {
          Converter con = new Converter(filename,outfilename,del);
          semaphore.acquire();
          con.start();
     }

    @Override
    public void run() {
        Logger.getLogger(Converter.class.getName()).log(Level.INFO, "Processing: " + filename);
        
         
        //metadata.add(Metadata.RESOURCE_NAME_KEY, p_document.getDocName());
       File file = new File(filename);
        TikaInputStream inS;
        try {
          
           
           Metadata metadata = new Metadata();
           metadata.set("Content-Encoding", "CP1250");
            inS = TikaInputStream.get(file, metadata);
          
            Tika tika =new Tika();
            tika.setMaxStringLength(10*1024*1024);
            String txt=tika.parseToString(inS,metadata);
            Pattern p = Pattern.compile("[\\p{Cf}\\p{Co}\\p{Cs}\\p{Cn}\\x00-\\x09\\x11-\\x1f]");
            txt = p.matcher(txt).replaceAll("");
        
           try {
                FileWriter fileWriter = new FileWriter(outfilename);
                try (BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) {
                    bufferedWriter.write(txt);
                }
                fileWriter.close();

            } catch (IOException exception) {
                Logger.getLogger(Converter.class.getName()).log(Level.SEVERE, "Problems with writing: " + outfilename, exception);
            }     
        
        
        
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Converter.class.getName()).log(Level.WARNING, "File not found", ex.getMessage());
        } catch (IOException | TikaException ex) {
            Logger.getLogger(Converter.class.getName()).log(Level.WARNING, "Porblems in Tika processing", ex.getMessage());
        }
        finally
        {  Logger.getLogger(Converter.class.getName()).log(Level.INFO, "Finished: " + outfilename);
            semaphore.release();
        }
       if (del) {
            file.delete();
        }
    }
    
}
