/*
 * Copyright (c) 2015, 2016 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.oomph.setup.internal.core;

import org.eclipse.oomph.preferences.util.PreferencesUtil;
import org.eclipse.oomph.preferences.util.PreferencesUtil.PreferenceProperty;
import org.eclipse.oomph.setup.util.StringExpander;
import org.eclipse.oomph.util.IOUtil;
import org.eclipse.oomph.util.StringUtil;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.xml.type.XMLTypeFactory;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Eike Stepper
 */
public class StringFilterRegistry
{
  public static final StringFilterRegistry INSTANCE = new StringFilterRegistry();

  private static final Pattern CAMEL_PATTERN = Pattern.compile("(?:[^\\p{Alnum}]+|^)(\\p{Lower})?");

  private final Map<String, StringFilter> filters = new HashMap<String, StringFilter>();

  private StringFilterRegistry()
  {
    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "file";
      }

      @Override
      public String getDescription()
      {
        return "Converts a file: URI to an OS-specific file system path.";
      }

      public String filter(String value)
      {
        return URI.createURI(value).toFileString();
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "uri";
      }

      @Override
      public String getDescription()
      {
        return "Converts a file system path to a file: URI.";
      }

      public String filter(String value)
      {
        return URI.createFileURI(value).toString();
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "uriLastSegment";
      }

      @Override
      public String getDescription()
      {
        return "Extracts the last path segment from a hierarchical URI or the authority from an opaque URI.";
      }

      public String filter(String value)
      {
        URI uri = URI.createURI(value);
        if (!uri.isHierarchical())
        {
          uri = URI.createURI(uri.opaquePart());
        }

        return URI.decode(uri.lastSegment());
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "gitRepository";
      }

      @Override
      public String getDescription()
      {
        return "Extracts the name of the repository from a Git URI (excluding a possible .git suffix).";
      }

      public String filter(String value)
      {
        URI uri = URI.createURI(value);
        if (!uri.isHierarchical())
        {
          uri = URI.createURI(uri.opaquePart());
        }

        String result = URI.decode(uri.lastSegment());
        if (result != null && result.endsWith(".git"))
        {
          result = result.substring(0, result.length() - 4);
        }

        return result;
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "username";
      }

      @Override
      public String getDescription()
      {
        return "Escapes all \"at\" symbols (@) of a String value, so that the result can be used in URI that contain a username.";
      }

      public String filter(String value)
      {
        return URI.encodeSegment(value, false).replace(":", "%3A").replace("@", "%40");
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "canonical";
      }

      @Override
      public String getDescription()
      {
        return "Canonicalizes a file system path.";
      }

      public String filter(String value)
      {
        // Don't canonicalize the value if it contains a unexpanded variable reference.
        if (StringExpander.STRING_EXPANSION_PATTERN.matcher(value).find())
        {
          return value;
        }

        File file = new File(value).getAbsoluteFile();

        try
        {
          return file.getCanonicalPath();
        }
        catch (IOException ex)
        {
          return file.getAbsolutePath();
        }
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "preferenceNode";
      }

      @Override
      public String getDescription()
      {
        return "Escapes all forward slashes (/) of a String value, so that the result can be used as a value in preference nodes.";
      }

      public String filter(String value)
      {
        return value.replaceAll("/", "\\\\2f");
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "length";
      }

      @Override
      public String getDescription()
      {
        return "Converts a String to a String that contains the alpha-numerical representation of the length of the original String.";
      }

      public String filter(String value)
      {
        return Integer.toString(value.length());
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "trim";
      }

      @Override
      public String getDescription()
      {
        return "Removes all whitespace from the beginning and the end of a String.";
      }

      public String filter(String value)
      {
        return value.trim();
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "trimLeft";
      }

      @Override
      public String getDescription()
      {
        return "Removes all whitespace from the beginning of a String.";
      }

      public String filter(String value)
      {
        return StringUtil.trimLeft(value);
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "trimRight";
      }

      @Override
      public String getDescription()
      {
        return "Removes all whitespace from the end of a String.";
      }

      public String filter(String value)
      {
        return StringUtil.trimRight(value);
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "trimTrailingSlashes";
      }

      @Override
      public String getDescription()
      {
        return "Removes all slashes and backslashes from the end of a String.";
      }

      public String filter(String value)
      {
        return StringUtil.trimTrailingSlashes(value);
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "upper";
      }

      @Override
      public String getDescription()
      {
        return "Converts all characters of a String value to upper-case.";
      }

      public String filter(String value)
      {
        return value.toUpperCase();
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "lower";
      }

      @Override
      public String getDescription()
      {
        return "Converts all characters of a String value to lower-case.";
      }

      public String filter(String value)
      {
        return value.toLowerCase();
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "cap";
      }

      @Override
      public String getDescription()
      {
        return "Capitalizes the first word of a String value.";
      }

      public String filter(String value)
      {
        return StringUtil.cap(value);
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "capAll";
      }

      @Override
      public String getDescription()
      {
        return "Capitalizes all words of a String value.";
      }

      @Override
      public String[] getDeprecations()
      {
        return new String[] { "allCap" };
      }

      public String filter(String value)
      {
        return StringUtil.capAll(value);
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "qualifiedName";
      }

      @Override
      public String getDescription()
      {
        return "Converts a camel case String value name to a qualified name.";
      }

      public String filter(String value)
      {
        return value.trim().replaceAll("[^\\p{Alnum}]+", ".").toLowerCase();
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "camel";
      }

      @Override
      public String getDescription()
      {
        return "Converts a qualified name to camel case notation.";
      }

      public String filter(String value)
      {
        Matcher matcher = CAMEL_PATTERN.matcher(value);
        StringBuffer result = new StringBuffer();
        while (matcher.find())
        {
          String group = matcher.group(1);
          matcher.appendReplacement(result, group == null ? "" : group.toUpperCase());
        }

        matcher.appendTail(result);

        return result.toString();
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "property";
      }

      @Override
      public String getDescription()
      {
        return "Escapes all double back slashes (\\\\) of a String value, so that the result can be used as a value in properties.";
      }

      public String filter(String value)
      {
        return value.replaceAll("\\\\", "\\\\\\\\");
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "path";
      }

      @Override
      public String getDescription()
      {
        return "Extracts the path segments from a URI.";
      }

      public String filter(String value)
      {
        return value.replaceAll("\\\\", "/");
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "basePath";
      }

      @Override
      public String getDescription()
      {
        return "Removes the last segment from a file system path.";
      }

      public String filter(String value)
      {
        value = value.replaceAll("\\\\", "/");
        int pos = value.lastIndexOf('/');
        if (pos == -1)
        {
          return "";
        }

        return value.substring(0, pos);
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "lastSegment";
      }

      @Override
      public String getDescription()
      {
        return "Extracts the last segment from a file system path.";
      }

      public String filter(String value)
      {
        int pos = Math.max(value.lastIndexOf('/'), value.lastIndexOf('\\'));
        if (pos == -1)
        {
          return value;
        }

        return value.substring(pos + 1);
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "fileExtension";
      }

      @Override
      public String getDescription()
      {
        return "Extracts the file extension from a URI or a file system path.";
      }

      public String filter(String value)
      {
        int pos = value.lastIndexOf('.');
        if (pos == -1)
        {
          return "";
        }

        return value.substring(pos + 1);
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "pathEncode";
      }

      @Override
      public String getDescription()
      {
        return "Converts a file system path to a String value that can be used as a file name.";
      }

      public String filter(String value)
      {
        return IOUtil.encodeFileName(value);
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "urlEncode";
      }

      @Override
      public String getDescription()
      {
        return "URL-encodes a String value.";
      }

      public String filter(String value)
      {
        try
        {
          return URLEncoder.encode(value, "UTF-8");
        }
        catch (UnsupportedEncodingException ex)
        {
          // Should not happen.
          return value;
        }
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "urlDecode";
      }

      @Override
      public String getDescription()
      {
        return "Decodes a URL.";
      }

      public String filter(String value)
      {
        try
        {
          return URLDecoder.decode(value, "UTF-8");
        }
        catch (UnsupportedEncodingException ex)
        {
          // Should not happen.
          return value;
        }
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "slashEncode";
      }

      @Override
      public String getDescription()
      {
        return "Encodes all slashes and backslashes of a String value.";
      }

      @SuppressWarnings("restriction")
      public String filter(String value)
      {
        try
        {
          return org.eclipse.equinox.internal.security.storage.SlashEncode.encode(value);
        }
        catch (Throwable ex)
        {
          // Should not happen.
          return value;
        }
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "slashDecode";
      }

      @Override
      public String getDescription()
      {
        return "Decodes a slashEncoded String value.";
      }

      @SuppressWarnings("restriction")
      public String filter(String value)
      {
        try
        {
          return org.eclipse.equinox.internal.security.storage.SlashEncode.decode(value);
        }
        catch (Throwable ex)
        {
          // Should not happen.
          return value;
        }
      }
    });

    registerFilter(new DocumentedStringFilter()
    {
      public String getName()
      {
        return "propertyValue";
      }

      @Override
      public String getDescription()
      {
        return "Interprets the String value as a preference property path and returns the value of that property.";
      }

      public String filter(String value)
      {
        PreferenceProperty preferenceProperty = new PreferencesUtil.PreferenceProperty(value);
        String result = preferenceProperty.get(null);
        return result == null ? "" : result;
      }
    });

    registerFilter("base64", new ParameterizedStringFilter()
    {
      public String filter(String value)
      {
        return filter(value, null);
      }

      public String filter(String value, String argument)
      {
        try
        {
          Charset charset;
          if (value.startsWith("<?xml"))
          {
            String xmlEncoding = URIConverter.ReadableInputStream.getEncoding(value);
            charset = Charset.forName(xmlEncoding == null ? "UTF-8" : xmlEncoding);
          }
          else if (argument != null)
          {
            charset = Charset.forName(argument.toUpperCase());
          }
          else
          {
            charset = Charset.defaultCharset();
          }

          return XMLTypeFactory.eINSTANCE.convertBase64Binary(value.getBytes(charset));
        }
        catch (Exception ex)
        {
          return value;
        }
      }
    });
  }

  public static void main(String[] args) throws UnsupportedEncodingException
  {
    List<Map.Entry<String, StringFilter>> entries = new ArrayList<Map.Entry<String, StringFilter>>(INSTANCE.filters.entrySet());
    Collections.sort(entries, new Comparator<Map.Entry<String, StringFilter>>()
    {
      public int compare(Map.Entry<String, StringFilter> e1, Map.Entry<String, StringFilter> e2)
      {
        return e1.getKey().compareTo(e2.getKey());
      }
    });

    System.out.println("{| class=\"wikitable\"");
    boolean first = true;

    for (Map.Entry<String, StringFilter> entry : entries)
    {
      String name;
      String description;

      StringFilter filter = entry.getValue();
      if (filter instanceof DocumentedStringFilter)
      {
        name = ((DocumentedStringFilter)filter).getName();
        description = ((DocumentedStringFilter)filter).getDescription();

        boolean deprecated = !name.toLowerCase().equals(entry.getKey().toLowerCase());
        if (deprecated)
        {
          continue;
        }
      }
      else
      {
        name = entry.getKey();
        description = "";
      }

      if (first)
      {
        first = false;
      }
      else
      {
        System.out.println("|-");
      }

      System.out.println("| '''" + name + "''' || " + description);
    }

    System.out.println("|}");
  }

  public String filter(String value, String filterName)
  {
    StringFilter filter = filters.get(filterName.toLowerCase());
    if (filter == null)
    {
      int argumentIndex = filterName.indexOf('.');
      if (argumentIndex != -1)
      {
        filter = filters.get(filterName.substring(0, argumentIndex).toLowerCase());
        if (filter instanceof ParameterizedStringFilter)
        {
          ParameterizedStringFilter parameterizedStringFilter = (ParameterizedStringFilter)filter;
          return parameterizedStringFilter.filter(value, filterName.substring(argumentIndex + 1));
        }
      }

      return value;
    }

    return filter.filter(value);
  }

  void initContributions()
  {
    if (SetupCorePlugin.INSTANCE.isOSGiRunning())
    {
      try
      {
        IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();

        for (IConfigurationElement configurationElement : extensionRegistry.getConfigurationElementsFor("org.eclipse.oomph.setup.core.stringFilters"))
        {
          String filterName = configurationElement.getAttribute("name");
          if (!filters.containsKey(filterName))
          {
            try
            {
              StringFilter filter = (StringFilter)configurationElement.createExecutableExtension("class");
              registerFilter(filterName, filter);
            }
            catch (Exception ex)
            {
              SetupCorePlugin.INSTANCE.log(ex);
            }
          }
        }
      }
      catch (Exception ex)
      {
        SetupCorePlugin.INSTANCE.log(ex);
      }
    }
  }

  private void registerFilter(String filterName, StringFilter filter)
  {
    filters.put(filterName.toLowerCase(), filter);
  }

  private void registerFilter(DocumentedStringFilter filter)
  {
    String name = filter.getName().toLowerCase();
    filters.put(name, filter);

    String[] deprecations = filter.getDeprecations();
    if (deprecations != null)
    {
      for (String deprecatedName : deprecations)
      {
        filters.put(deprecatedName.toLowerCase(), filter);
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  public static abstract class DocumentedStringFilter implements StringFilter, StringFilterDocumentation
  {
    public String getDescription()
    {
      return null;
    }

    public String[] getDeprecations()
    {
      return null;
    }
  }
}
