/**************************************************************************
 OmegaT - Computer Assisted Translation (CAT) tool
          with fuzzy matching, translation memory, keyword search,
          glossaries, and translation leveraging into updated projects.

 Copyright (C) 2017 Thomas Cordonnier
               Home page: http://www.omegat.org/
               Support center: http://groups.yahoo.com/group/OmegaT/

 This file is part of OmegaT.

 OmegaT is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 OmegaT is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 **************************************************************************/

package org.omegat.filehooks;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;

import org.omegat.core.Core;
import org.omegat.core.data.SourceTextEntry;
import org.omegat.core.data.ProjectProperties;
import org.omegat.util.Preferences;
import org.omegat.util.Log;

/**
 * Hook used by renumeroted XLIFF files: call renum-to-trados.pl after compilation
 * 
 * @author Thomas CORDONNIER
 */
public class RenumXliffHook implements IFileHook {
	
    public static final String SOURCE_TRADOS_DIR = "source-trados", COMPILED_TRADOS_DIR = "target-trados";
		
	@Override
	public String getNativeSourceFile (String currentFile, SourceTextEntry entry) {
		currentFile = currentFile.replace("/", File.separator);
		ProjectProperties otProj = Core.getProject().getProjectProperties();
		try { 
			File handler = new File (currentFile);
			handler = new File(handler.getParentFile().getParentFile(), SOURCE_TRADOS_DIR);
			handler = new File(handler, currentFile.substring(otProj.getSourceRoot().length()).replace(".renum.xlf",".sdlxliff"));
			if (handler.exists()) // use XLIFF_HOOK, which is able to extract the file, if necessary
				return XLIFF_HOOK.getNativeSourceFile(handler.getCanonicalPath(), entry, otProj.getProjectRoot() + SOURCE_TRADOS_DIR + File.separator);
			else {	// source sdlxiff not present. Will not be able to rebuild target, but search other ways to view source
				String nativeFile = currentFile.substring(0, currentFile.lastIndexOf('.')); nativeFile = nativeFile.substring(0, nativeFile.lastIndexOf('.')); // .renum.xlf
				// Try same directory, then original, then source-native
				handler = new File(nativeFile); if (handler.exists()) return nativeFile;			
				handler = new File(new File(handler.getParentFile().getParentFile(), XLIFF_HOOK.ORIGINAL_NATIVE_DIR), nativeFile); if (handler.exists()) return handler.getCanonicalPath();
				handler = new File(new File(handler.getParentFile().getParentFile(), XLIFF_HOOK.SOURCE_NATIVE_DIR), nativeFile); if (handler.exists()) return handler.getCanonicalPath();
				// Try the file declared in the renum.xlf (identical to sdlxliff)
				return XLIFF_HOOK.readOriginalFileName(currentFile).getCanonicalPath(); 
			}
		} catch (Exception e) { // all failed
			return currentFile; 
		}
	}	

	private Exception lastCompileException = null;
	public Exception lastCompileException() { return lastCompileException; } 
	
	@Override public String getNativeTargetFile (String currentFile) { return XLIFF_HOOK.getNativeTargetFile(currentFile); }
	
	@Override 
	public void postCompile(File destDir, String midName) {
        final String extraScripts = Preferences.getPreferenceDefault(Preferences.SCRIPTS_DIRECTORY, 
			System.getenv("OMEGAT_HOME") + File.separator + "scripts")  
			+ File.separator + "extra" + File.separator;
        try {
            // First, try to rebuild the sdlxliff file with correct renumerotation
            // Original file must be in SOURCE_TRADOS_DIR, then target will be in COMPILED_TRADOS_DIR
            File oriSdlxliff = new File (destDir.getParentFile() + File.separator + SOURCE_TRADOS_DIR + File.separator + midName.replace(".renum.xlf", ".sdlxliff"));
            if (! oriSdlxliff.exists()) { 
                oriSdlxliff = XLIFF_HOOK.readOriginalFileName(destDir.getCanonicalPath() + File.separator + midName);
                oriSdlxliff = new File (oriSdlxliff.getParentFile() + "\\" + midName.replace(".renum.xlf", ".sdlxliff"));
            }
			if (! oriSdlxliff.exists()) { lastCompileException = new java.io.FileNotFoundException("Need source sdlxliff to rebuild native file"); return; }            
			File tmpDestFile = new File (destDir.getParentFile(), COMPILED_TRADOS_DIR); if (! tmpDestFile.exists()) tmpDestFile.mkdirs();
            tmpDestFile = new File (tmpDestFile, midName.replace(".renum.xlf", ".sdlxliff"));
			System.err.println("perl " + extraScripts +  "\\renum-to-trados.pl "
				+ oriSdlxliff.getPath() + " " + destDir.getPath() + "\\" + midName + " " + tmpDestFile.getPath());	
            Process p = Runtime.getRuntime().exec (new String[] { 
                Preferences.getPreferenceDefault(Preferences.PERL_PATH, "perl"), extraScripts +  "\\renum-to-trados.pl",  
                oriSdlxliff.getPath(), destDir.getPath() + "\\" + midName, 
                Core.getProject().getProjectProperties().getProjectRoot() + "\\omegat\\project_save.tmx", tmpDestFile.getPath()								
            });
			String line;
			System.err.println("Reading getInputStream");
			try (BufferedReader reader = new BufferedReader(new InputStreamReader (p.getInputStream()))) {
				while ((line = reader.readLine()) != null) System.err.println ("[PERL OUT]: " + line);
			}
			System.err.println("Reading getErrorStream");
			try (BufferedReader reader = new BufferedReader(new InputStreamReader (p.getErrorStream()))) {
				while ((line = reader.readLine()) != null) System.err.println ("[PERL ERR]: " + line);
			}
            p.waitFor();
			// Now we have an SDLXLIFF under COMPILED_TRADOS_DIR; use standard XLIFF 
			XLIFF_HOOK.postCompile(
				new File (destDir.getParentFile(), XliffFileHook.COMPILED_NATIVE_DIR), // Compile to target-native
				midName.replace(".renum.xlf", ".sdlxliff"), // source = result from perl...
				destDir.getParentFile() + File.separator + COMPILED_TRADOS_DIR + File.separator);	// ...which is in COMPILED_TRADOS_DIR
			lastCompileException = XLIFF_HOOK.lastCompileException(); 
        } catch (Exception eEx) {
            lastCompileException = eEx; eEx.printStackTrace(); Log.log (eEx); 
        }
	}	
	
	@Override public boolean supportsOpenInStudio(String file) { return true; }

	@Override
	public String getTradosTargetFile (String currentFile) {  
		return currentFile.replaceAll("\\btarget(\\.tmp)?\\b", COMPILED_TRADOS_DIR).replace(".renum.xlf", ".sdlxliff");
	}

}
