/*
 * 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 java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.commons.io.IOUtils;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.update.AddUpdateCommand;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A processor which will match content of "inputField" against regular expressions
 * found in "boostFilename", and if it matches will return the corresponding boost
 * value from the file and output this to "boostField" as a double value.
 * If more than one pattern matches, the boosts from each are multiplied.
 * <p>
 * A typical use case may be to match a URL against patterns to boost or deboost
 * web documents based on the URL itself:
 * <pre>
 * # Format of each line: &lt;pattern&gt;&lt;TAB&gt;&lt;boost&gt;
 * # Example:
 * https?://my.domain.com/temp.*  0.2
 * </pre>
 * <p>
 * Both inputField, boostField and boostFilename are mandatory parameters.
 */
public class RegexpBoostProcessor extends UpdateRequestProcessor {

  protected static final String INPUT_FIELD_PARAM = "inputField";
  protected static final String BOOST_FIELD_PARAM = "boostField";
  protected static final String BOOST_FILENAME_PARAM = "boostFilename";
  private static final String DEFAULT_INPUT_FIELDNAME = "url";
  private static final String DEFAULT_BOOST_FIELDNAME = "urlboost";

  private static final Logger log = LoggerFactory.getLogger(RegexpBoostProcessor.class);

  private boolean enabled = true;
  private String inputFieldname = DEFAULT_INPUT_FIELDNAME;
  private String boostFieldname = DEFAULT_BOOST_FIELDNAME;
  private String boostFilename;
  private List<BoostEntry> boostEntries = new ArrayList<>();
  private static final String BOOST_ENTRIES_CACHE_KEY = "boost-entries";

  RegexpBoostProcessor(SolrParams parameters,
                       SolrQueryRequest request,
                       SolrQueryResponse response,
                       UpdateRequestProcessor nextProcessor,
                       final Map<Object, Object> sharedObjectCache) {
    super(nextProcessor);
    this.initParameters(parameters);

    if (this.boostFilename == null) {
      log.warn("Null boost filename.  Disabling processor.");
      setEnabled(false);
    }

    if (!isEnabled()) {
      return;
    }

    try {
      synchronized (sharedObjectCache) {
        List<BoostEntry> cachedBoostEntries =
            (List<BoostEntry>) sharedObjectCache.get(BOOST_ENTRIES_CACHE_KEY);

        if (cachedBoostEntries == null) {
          log.debug("No pre-cached boost entry list found, initializing new");
          InputStream is = request.getCore().getResourceLoader().openResource(boostFilename);
          cachedBoostEntries = initBoostEntries(is);
          sharedObjectCache.put(BOOST_ENTRIES_CACHE_KEY, cachedBoostEntries);
        } else {
          if (log.isDebugEnabled()) {
            log.debug("Using cached boost entry list with " + cachedBoostEntries.size() + " elements.");
          }
        }

        this.boostEntries = cachedBoostEntries;
      }
    } catch (IOException ioe) {
      log.warn("IOException while initializing boost entries from file " + this.boostFilename, ioe);
    }
  }

  private void initParameters(SolrParams parameters) {
    if (parameters != null) {
      this.setEnabled(parameters.getBool("enabled", true));
      this.inputFieldname = parameters.get(INPUT_FIELD_PARAM, DEFAULT_INPUT_FIELDNAME);
      this.boostFieldname = parameters.get(BOOST_FIELD_PARAM, DEFAULT_BOOST_FIELDNAME);
      this.boostFilename = parameters.get(BOOST_FILENAME_PARAM);
    }
  }

  private List<BoostEntry> initBoostEntries(InputStream is) throws IOException {
    List<BoostEntry> newBoostEntries = new ArrayList<>();
    
    BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
    try {
      String line = null;
      while ((line = reader.readLine()) != null) {
        // Remove comments
        line = line.replaceAll("\\s+#.*$", "");
        line = line.replaceAll("^#.*$", "");

        // Skip empty lines or comment lines
        if (line.trim().length() == 0) {
          continue;
        }

        String[] fields = line.split("\\s+");

        if (fields.length == 2) {
          String regexp = fields[0];
          String boost = fields[1];
          newBoostEntries.add(new BoostEntry(Pattern.compile(regexp), Double.parseDouble(boost)));
          log.debug("Read regexp " + regexp + " with boost " + boost);
        } else {
          log.warn("Malformed config input line: " + line + " (expected 2 fields, got " + fields.length + " fields).  Skipping entry.");
          continue;
        }
      }
    } finally {
      IOUtils.closeQuietly(reader);
    }

    return newBoostEntries;
  }

  @Override
  public void processAdd(AddUpdateCommand command) throws IOException {
    if (isEnabled()) {
      processBoost(command);
    }
    super.processAdd(command);
  }

  public void processBoost(AddUpdateCommand command) {
    SolrInputDocument document = command.getSolrInputDocument();
    if (document.containsKey(inputFieldname)) {
      String value = (String) document.getFieldValue(inputFieldname);
      double boost = 1.0f;
      for (BoostEntry boostEntry : boostEntries) {
        if (boostEntry.getPattern().matcher(value).matches()) {
          if (log.isDebugEnabled()) {
            log.debug("Pattern match " + boostEntry.getPattern().pattern() + " for " + value);
          }
          boost = (boostEntry.getBoost() * 1000) * (boost * 1000) / 1000000;
        }
      }
      document.setField(boostFieldname, boost);

      if (log.isDebugEnabled()) {
        log.debug("Value " + boost + ", applied to field " + boostFieldname);
      }
    }
  }

  public boolean isEnabled() {
    return enabled;
  }

  public void setEnabled(boolean enabled) {
    this.enabled = enabled;
  }

  private static class BoostEntry {

    private Pattern pattern;
    private double boost;

    public BoostEntry(Pattern pattern, double d) {
      this.pattern = pattern;
      this.boost = d;
    }

    public Pattern getPattern() {
      return pattern;
    }

    public double getBoost() {
      return boost;
    }
  }
}
