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

 Copyright (C) 2010 Alex Buloichik, Ibai Lakunza Velasco, Didier Briel
               2013 Martin Wunderlich, Didier Briel, 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.core.matching.external;

import java.io.InputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Properties;
import java.util.Iterator;

import org.omegat.core.data.PrepareTMXEntry;
import org.omegat.util.Preferences;
import org.omegat.util.TMXReader2;
import org.omegat.util.OStrings;
import org.omegat.util.Language;
import org.omegat.util.WikiGet;
import org.omegat.util.Token;



/**
 * Access to MyMemory as an external translation memory (not a machine translator) <br>
 * 
 * @author Ibai Lakunza Velasco
 * @author Didier Briel
 * @author Martin Wunderlich
 * @author Thomas Cordonnier
 */
public class MyMemory extends MenuMemory {

    private static final String MYMEMORY_API_EMAIL = "mymemory.api.email";
    
    // ----------------------- Access to web service -----------------
    
    protected static String GT_URL = "https://mymemory.translated.net/api/get?q=";
    protected static String GT_URL2 = "&langpair=#sourceLang#|#targetLang#&of=#format#";
    protected static String XPATH_QUERY_ALL_TU = "//tu"; 
    protected static String XPATH_QUERY_TUV = "child::tuv[starts-with(@lang, '#langCode#')]/seg/text()"; // MyMemory always returns a 4-letter locale code, even when the query contains a language code only; to make sure we get the right matches, only the language code is taken into account
    
    /**
     * Modify some country codes to fit with MyMemory
     * 
     * @param language
     *            An OmegaT language
     * @return A code modified for MyMemory languages
     */
    protected String mymemoryCode(Language language) {
        String lCode = language.getLanguageCode().toLowerCase();
        return lCode;
    }
    
    /**
     * Builds the URL for the XML query
     */
    protected String buildMyMemoryUrl(Language sLang, Language tLang, String text, String format) throws UnsupportedEncodingException {
        String sourceLang = mymemoryCode(sLang);
        String targetLang = mymemoryCode(tLang);
        String url2 = GT_URL2.replace("#sourceLang#", sourceLang).replace("#targetLang#", targetLang).replace("#format#", format);
        String url = GT_URL + URLEncoder.encode(text, "UTF-8") + url2;
    
        return url;
    }   
    
    protected InputStream getMyMemoryResponse(Language sLang, Language tLang, String text, String format) throws UnsupportedEncodingException, IOException {
        String url = buildMyMemoryUrl(sLang, tLang, text, format);

        // Get email from systemProperties to enable 1000rq/day instead of 100 rq/day
        String email = System.getProperty(MYMEMORY_API_EMAIL);
        if ((email != null) && ! ("".equals(email))) {
            url = url + "&de=" + email;
        }
        
        // Get the results from MyMemory
        return new java.net.URL(url).openStream();
    }
    
    // ----------------------- IExternalMemory interface -----------------
    
    @Override
    protected String getPreferenceName() {
        return "allow_mymemory_translation_memory";	// plugin, so not in Preferences
    }

    @Override
    public String getProviderName() {
        return OStrings.getString("MT_ENGINE_MYMEMORY_HUMAN");
    }
    
    @Override
    public String getMemoryName() {
        return OStrings.getString("MT_ENGINE_MYMEMORY_HUMAN");
    }
    
    public static final SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'", java.util.Locale.ENGLISH);
    
    public List<PrepareTMXEntry> retreiveMatchingTranslations (Language sLang, Language tLang, String text, int minScore, int maxCount) throws Exception {
		final List<PrepareTMXEntry> entries = new ArrayList<PrepareTMXEntry>();
		
        TMXReader2 reader = new TMXReader2();
		reader.readTMX(getMyMemoryResponse(sLang, tLang, text, "tmx"), 
			sLang, tLang, true, false, false, false,
			(TMXReader2.ParsedTu tu, TMXReader2.ParsedTuv tuvSource, TMXReader2.ParsedTuv tuvTarget, boolean isParagraphSegtype) -> {
				PrepareTMXEntry entry = new PrepareTMXEntry();
				entry.source = tuvSource.text; entry.translation = tuvTarget.text;
				
				entry.creator = tuvTarget.creationid == null ? tu.creationid : tuvTarget.creationid;
				entry.creationDate = tuvTarget.creationdate == 0 ? tu.creationdate : tuvTarget.creationdate;
				entry.changer = tuvTarget.changeid == null ? tu.changeid : tuvTarget.changeid;
				entry.changeDate = tuvTarget.changedate == 0 ? tu.changedate : tuvTarget.changedate;
				entries.add (entry);
				return true;
			});
		
        return entries;
    }
    
}
