/*
 * Copyright 2010 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.validation.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.shared.GwtLocale;
import com.google.gwt.regexp.shared.MatchResult;
import com.google.gwt.regexp.shared.RegExp;

import java.util.Map;

import javax.validation.MessageInterpolator;
import javax.validation.metadata.ConstraintDescriptor;

/**
 * <strong>EXPERIMENTAL</strong> and subject to change. Do not use this in
 * production code.
 * <p>
 * Base GWT {@link MessageInterpolator}.
 */
public abstract class BaseMessageInterpolator implements MessageInterpolator {

  /**
   * Implementation of {@link Context}.
   */
  public static class ContextImpl implements Context {

    private final ConstraintDescriptor<?> constraintDescriptor;
    private final Object value;

    public ContextImpl(ConstraintDescriptor<?> constraintDescriptor, Object value) {
      this.constraintDescriptor = constraintDescriptor;
      this.value = value;
    }

    public ConstraintDescriptor<?> getConstraintDescriptor() {
      return constraintDescriptor;
    }

    public Object getValidatedValue() {
      return value;
    }
  }

  // local version because guava is included.
  private static interface Function<F, T> {
    T apply(F from);
  }

  /**
   * Regular expression used to do message interpolation.
   */
  private static final RegExp MESSAGE_PARAMETER_PATTERN = RegExp.compile(
      "(\\{[^\\}]+?\\})", "g");

  // Visible for testing
  static Function<String, String> createAnnotationReplacer(
      final Map<String, Object> map) {
    return new Function<String, String>() {

      public String apply(String from) {
        Object object = map.get(from);
        return object == null ? null : object.toString();
      }
    };
  }

  private static Function<String, String> createReplacer(
      final ValidationMessageResolver messageResolver) {
    return new Function<String, String>() {
      public String apply(String from) {
        Object object = messageResolver.get(from);
        return object == null ? null : object.toString();
      }
    };
  }

  /**
   * Replaces keys using the Default Validation Provider properties.
   */
  private final Function<String, String> providerReplacer =
      createReplacer((ValidationMessageResolver)
          GWT.create(ProviderValidationMessageResolver.class));

  /**
   * Replaces keys using the Validation User custom properties.
   */
  private final Function<String, String> userReplacer =
      createReplacer((ValidationMessageResolver)
          GWT.create(UserValidationMessagesResolver.class));

  public String interpolate(String messageTemplate, Context context) {
    return gwtInterpolate(messageTemplate, context, null);
  }

  protected String gwtInterpolate(String message, Context context,
      GwtLocale locale) {
    // see Section 4.3.1.1
    String resolvedMessage = message;
    String step1message;

    // TODO(nchalko) Add a safety to make sure this does not loop forever.
    do {
      do {
        step1message = resolvedMessage;

        // Step 1 Replace message parameters using custom user messages
        // repeat
        resolvedMessage = replaceParameters(resolvedMessage, userReplacer);
      } while (!step1message.equals(resolvedMessage));

      // Step2 Replace message parameter using the default provider messages.
      resolvedMessage = replaceParameters(resolvedMessage, providerReplacer);

      // Step 3 repeat from step 1 if step 2 made changes.
    } while (!step1message.equals(resolvedMessage));

    // step 4 resolve annotation attributes
    resolvedMessage = replaceParameters(
        resolvedMessage,
        createAnnotationReplacer(context.getConstraintDescriptor().getAttributes()));

    // Remove escapes (4.3.1)
    resolvedMessage = resolvedMessage.replace("\\{", "{");
    resolvedMessage = resolvedMessage.replace("\\}", "}");
    resolvedMessage = resolvedMessage.replace("\\\\", "\\");
    return resolvedMessage;
  }

  protected String replaceParameters(String message,
      Function<String, String> replacer) {
    StringBuffer sb = new StringBuffer();
    int index = 0;

    MatchResult matcher;
    while ((matcher = MESSAGE_PARAMETER_PATTERN.exec(message)) != null) {
      String matched = matcher.getGroup(0);
      sb.append(message.substring(index, matcher.getIndex()));
      Object value = replacer.apply(removeCurlyBrace(matched));
      sb.append(value == null ? matched : value);
      index = MESSAGE_PARAMETER_PATTERN.getLastIndex();
    }
    if (index < message.length()) {
      sb.append(message.substring(index));
    }
    return sb.toString();
  }

  private String removeCurlyBrace(String parameter) {
    return parameter.substring(1, parameter.length() - 1);
  }
}
