content: /*
   *  Copyright (C) 2013-2015 Stichting Akvo (Akvo Foundation)
   *
   *  This file is part of Akvo FLOW.
   *
   *  Akvo FLOW is free software: you can redistribute it and modify it under the terms of
   *  the GNU Affero General Public License (AGPL) as published by the Free Software Foundation,
   *  either version 3 of the License or any later version.
   *
   *  Akvo FLOW 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 Affero General Public License included below for more details.
   *
   *  The full license text can also be seen at <http://www.gnu.org/licenses/agpl.html>.
   */
  
  package services;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.Properties;
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  
  import org.apache.commons.io.FileUtils;
  
  public class TranslationGenerator {
  
      private static final Map<String, String> PATTERNS = new HashMap<String, String>();
      private static final Pattern ANCHOR = Pattern.compile("<a.*?>.*?</a>");
      private static final Pattern T_HELPER = Pattern.compile("\\{\\{t\\s\\_\\w+\\}\\}");
      private static final Pattern BINDING = Pattern.compile(">\\{\\{.*?\\}\\}<");
      private static final Pattern AKVO_ORG = Pattern.compile(">akvo.org</a>");
  
      static {
          PATTERNS.put("{{t ", "}}");
          PATTERNS.put("{{tooltip ", "}}");
          PATTERNS.put("promptBinding=\"Ember.STRINGS.", "\"");
          PATTERNS.put("placeholderBinding=\"Ember.STRINGS.", "\"");
          PATTERNS.put("String.loc('", "'");
          PATTERNS.put("(t> ", ")");
          PATTERNS.put("Ember.String.loc('", "'");
      }
  
      private static final String[] EXTS = {
              "handlebars", "js", "cljs", "jsx"
      };
  
      public static void main(String[] args) throws Exception {
  
          if (args.length < 2) {
              System.err.println("<Dashboard> and <output> directories are required");
              return;
          }
  
          final File sources = new File(args[0]);
          final File output = new File(args[1]);
  
          final Properties ui_strings = new Properties();
          ui_strings.load(new FileInputStream(new File(output,
                  "/ui-strings.properties")));
  
          final Map<String, String> trlKeys = new HashMap<String, String>();
          final List<String> enValues = new ArrayList<String>();
  
          for (File f : (List<File>) FileUtils.listFiles(sources, EXTS, true)) {
              if (f.getAbsolutePath().contains("vendor")
                      || f.getAbsolutePath().contains("plugins")
                      || f.getAbsolutePath().contains("tests")) {
                  continue; // skipping
              }
  
              final List<String> lines = FileUtils.readLines(f, "UTF-8");
              int ln = 1;
              for (String line : lines) {
                  if (containsTranslatableKeys(line)) {
                      final List<String> keys = getKeys(line);
                      if (!keys.isEmpty()) {
                          for (String k : keys) {
                              if (trlKeys.containsKey(k)) {
                                  continue; // skip
                              }
                              final String en = ui_strings.getProperty(k);
                              if (en == null) {
                                  System.err.println("Translation key `"
                                          + k
                                          + "` not found in ui-strings.properties");
                                  ui_strings.put(k, "");
                              }
  
                              trlKeys.put(k, (en == null ? "" : en));
  
                              if (en != null && !"".equals(en)
                                      && !enValues.contains(en)) {
                                  enValues.add(en);
                              }
                          }
                      }
                  }
                  if (f.getAbsolutePath().endsWith(".handlebars") &&
                          containsMissingTranslation(line)) {
                      System.err.println("Check for missing translation in " + f.getName() + ":" + ln
                              + " " + line);
                  }
                  ln++;
              }
          }
  
          Collections.sort(enValues);
          StringBuffer sb = new StringBuffer();
          for (String val : enValues) {
              sb.append(val.replaceAll(" ", "\\\\ ")).append(" = ").append(val)
                      .append("\n");
          }
          FileUtils.writeStringToFile(new File(output, "/en.properties"),
                  sb.toString(), "ISO-8859-1");
  
          final List<String> tmp = new ArrayList<String>(trlKeys.keySet());
          Collections.sort(tmp);
          final StringBuffer uisource = new StringBuffer();
          for (String ui : tmp) {
              uisource.append(ui).append(" = ").append(trlKeys.get(ui))
                      .append("\n");
          }
          FileUtils.writeStringToFile(new File(output, "/ui-strings.properties"),
                  uisource.toString(), "ISO-8859-1");
      }
  
      private static boolean containsMissingTranslation(String line) {
          final Matcher m = ANCHOR.matcher(line);
          if (!m.find()) {
              return false;
          }
          final Matcher m2 = T_HELPER.matcher(m.group());
          final Matcher m3 = BINDING.matcher(m.group());
          final Matcher m4 = AKVO_ORG.matcher(m.group()); // Hack to remove false positive
          if (!m2.find() && !m3.find() && !m4.find()) {
              return true;
          }
          return false;
      }
  
      private static boolean containsTranslatableKeys(String line) {
          for (String pattern : PATTERNS.keySet()) {
              if (line.contains(pattern)) {
                  return true;
              }
          }
          return false;
      }
  
      private static List<String> getKeys(String line) {
  
          if (!containsTranslatableKeys(line)) {
              return Collections.emptyList();
          }
  
          final List<String> keys = new ArrayList<String>();
          for (String pattern : PATTERNS.keySet()) {
              keys.addAll(getKeysFromLine(line, pattern, PATTERNS.get(pattern)));
          }
  
          return keys;
      }
  
      private static List<String> getKeysFromLine(String line, String prefix,
              String suffix) {
  
          final List<String> keys = new ArrayList<String>();
  
          int start = line.indexOf(prefix);
          int end = -1;
  
          if (start != -1) {
              start += prefix.length();
              end = line.indexOf(suffix, start);
          }
  
          while (start > 0 && end > 0) {
              keys.add(line.substring(start, end));
              start = line.indexOf(prefix, end + 1);
              if (start == -1) {
                  break;
              }
              start = start + prefix.length();
              end = line.indexOf(suffix, start);
          }
  
          return keys;
      }
  
  }
  