/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.solr.update.processor;

import static org.apache.solr.update.processor.FieldValueMutatingUpdateProcessor.valueMutator;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;


/**
 * An updated processor that applies a configured regex to any 
 * CharSequence values found in the selected fields, and replaces 
 * any matches with the configured replacement string.
 *
 * <p>
 * By default this processor applies itself to no fields.
 * </p>
 *
 * <p>
 * By default, <code>literalReplacement</code> is set to true, in which
 * case, the <code>replacement</code> string will be treated literally by
 * quoting via {@link Matcher#quoteReplacement(String)}. And hence, '\'
 * and '$' signs will not be processed. When <code>literalReplacement</code>
 * is set to false, one can perform backreference operations and capture
 * group substitutions.
 * </p>
 *
 * <p>
 * For example, with the configuration listed below, any sequence of multiple 
 * whitespace characters found in values for field named <code>title</code> 
 * or <code>content</code> will be replaced by a single space character.
 * </p>
 *
 * <pre class="prettyprint">
 * &lt;processor class="solr.RegexReplaceProcessorFactory"&gt;
 *   &lt;str name="fieldName"&gt;content&lt;/str&gt;
 *   &lt;str name="fieldName"&gt;title&lt;/str&gt;
 *   &lt;str name="pattern"&gt;\s+&lt;/str&gt;
 *   &lt;str name="replacement"&gt; &lt;/str&gt;
 *   &lt;bool name="literalReplacement"&gt;true&lt;/bool&gt;
 * &lt;/processor&gt;</pre>
 *
 * @see java.util.regex.Pattern
 * @since 4.0.0
 */
public final class RegexReplaceProcessorFactory extends FieldMutatingUpdateProcessorFactory {
  
  private static final String REPLACEMENT_PARAM = "replacement";
  private static final String PATTERN_PARAM = "pattern";
  private static final String LITERAL_REPLACEMENT_PARAM = "literalReplacement";
  
  private Pattern pattern;
  private String replacement;
  // by default, literalReplacementEnabled is set to true to allow backward compatibility
  private boolean literalReplacementEnabled = true;

  @SuppressWarnings("unchecked")
  @Override
  public void init(NamedList args) {

    Object patternParam = args.remove(PATTERN_PARAM);

    if (patternParam == null) {
      throw new SolrException(ErrorCode.SERVER_ERROR, 
                              "Missing required init parameter: " + PATTERN_PARAM);
    }
    
    try {
      pattern = Pattern.compile(patternParam.toString());      
    } catch (PatternSyntaxException e) {
      throw new SolrException(ErrorCode.SERVER_ERROR, 
                              "Invalid regex: " + patternParam, e);
    }                                

    Object replacementParam = args.remove(REPLACEMENT_PARAM);
    if (replacementParam == null) {
      throw new SolrException(ErrorCode.SERVER_ERROR, 
                              "Missing required init parameter: " + REPLACEMENT_PARAM);
    }

    Boolean literalReplacement = args.removeBooleanArg(LITERAL_REPLACEMENT_PARAM);

    if (literalReplacement != null) {
      literalReplacementEnabled = literalReplacement;
    }

    if (literalReplacementEnabled) {
      replacement = Matcher.quoteReplacement(replacementParam.toString());
    } else {
      replacement = replacementParam.toString();
    }

    super.init(args);
  }

  /** 
   * @see FieldMutatingUpdateProcessor#SELECT_NO_FIELDS
   */
  @Override
  protected FieldMutatingUpdateProcessor.FieldNameSelector 
    getDefaultSelector(final SolrCore core) {

    return FieldMutatingUpdateProcessor.SELECT_NO_FIELDS;

  }
  
  @Override
  public UpdateRequestProcessor getInstance(SolrQueryRequest request,
                                            SolrQueryResponse response,
                                            UpdateRequestProcessor next) {
    return valueMutator(getSelector(), next, src -> {
      if (src instanceof CharSequence) {
        CharSequence txt = (CharSequence) src;
        return pattern.matcher(txt).replaceAll(replacement);
      }
      return src;
    });
  }
}
