/*
 * 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.olingo.server.core.prefer;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.olingo.server.api.prefer.Preferences.Preference;

/**
 * <p>Parses the values of <code>Prefer</code> HTTP header fields.</p>
 * <p>See <a href="https://www.ietf.org/rfc/rfc7240.txt">RFC 7240</a> for details;
 * there the following grammar is defined:</p>
 * <pre>
 * Prefer = "Prefer" ":" 1#preference
 * preference = token [ BWS "=" BWS word ] *( OWS ";" [ OWS parameter ] )
 * parameter = token [ BWS "=" BWS word ]
 * token = 1*tchar
 * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
 * / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
 * word = token / quoted-string
 * quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE
 * qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / %x80-FF
 * quoted-pair = "\" ( HTAB / SP / %x21-7E / %x80-FF )
 * OWS = *( SP / HTAB ) ; optional whitespace
 * BWS = OWS ; "bad" whitespace
 * </pre>
 * <p>Values with illegal syntax do not contribute to the result but no exception is thrown.</p>
 */
public class PreferParser {

  private static final String TOKEN = "(?:[-!#$%&'*+.^_`|~]|\\w)+";
  private static final String QUOTED_STRING = "(?:\"(?:[\\t !#-\\[\\]-~\\x80-\\xFF]|"
      + "(?:\\\\[\\t !-~\\x80-\\xFF]))*\")";
  private static final String NAMED_VALUE =
      "(" + TOKEN + ")(?:\\s*=\\s*(" + TOKEN + "|" + QUOTED_STRING + "))?";
  private static final Pattern PREFERENCE = Pattern.compile("\\s*(,\\s*)+|"
      + "(?:" + NAMED_VALUE + "((?:\\s*;\\s*(?:" + NAMED_VALUE + ")?)*))");
  private static final Pattern PARAMETER = Pattern.compile("\\s*(;\\s*)+|(?:" + NAMED_VALUE + ")");

  private PreferParser() {
    // Private constructor for utility classes
  }

  protected static Map<String, Preference> parse(final Collection<String> values) {
    if (values == null || values.isEmpty()) {
      return Collections.emptyMap();
    }

    Map<String, Preference> result = new HashMap<>();
    for (final String value : values) {
      if (value != null && !value.isEmpty()) {
        parse(value, result);
      }
    }
    return result;
  }

  private static void parse(final String value, final Map<String, Preference> result) {
    Map<String, Preference> partResult = new HashMap<>();
    String separator = "";
    int start = 0;
    Matcher matcher = PREFERENCE.matcher(value.trim());
    while (matcher.find() && matcher.start() == start) {
      start = matcher.end();
      if (matcher.group(1) != null) {
        separator = matcher.group(1);
      } else if (separator != null) {
        final String name = matcher.group(2).toLowerCase(Locale.ROOT);
        // RFC 7240:
        // If any preference is specified more than once, only the first instance is to be
        // considered. All subsequent occurrences SHOULD be ignored without signaling
        // an error or otherwise altering the processing of the request.
        if (!partResult.containsKey(name)) {
          final String preferenceValue = getValue(matcher.group(3));
          final Map<String, String> parameters =
              matcher.group(4) == null || matcher.group(4).isEmpty() ? null :
                parseParameters(matcher.group(4));
          partResult.put(name, new Preference(preferenceValue, parameters));
        }
        separator = null;
      } else {
        return;
      }
    }
    if (matcher.hitEnd()) {
      // Here we also have to keep already existing preferences.
      for (final Map.Entry<String, Preference> entry : partResult.entrySet()) {
        if (!result.containsKey(entry.getKey())) {
          result.put(entry.getKey(), entry.getValue());
        }
      }
    }
  }

  private static Map<String, String> parseParameters(final String parameters) {
    Map<String, String> result = new HashMap<>();
    String separator = "";
    int start = 0;
    Matcher matcher = PARAMETER.matcher(parameters.trim());
    while (matcher.find() && matcher.start() == start) {
      start = matcher.end();
      if (matcher.group(1) != null) {
        separator = matcher.group(1);
      } else if (separator != null) {
        final String name = matcher.group(2).toLowerCase(Locale.ROOT);
        // We have to keep already existing parameters.
        if (!result.containsKey(name)) {
          result.put(name, getValue(matcher.group(3)));
        }
        separator = null;
      } else {
        return null;
      }
    }
    return matcher.hitEnd() ? Collections.unmodifiableMap(result) : null;
  }

  private static String getValue(final String value) {
    if (value == null) {
      return null;
    }
    String result = value;
    if (value.startsWith("\"")) {
      result = value.substring(1, value.length() - 1);
    }
    // Unquote backslash-quoted characters.
    if (result.indexOf('\\') >= 0) {
      result = result.replaceAll("\\\\(.)", "$1");
    }
    return result;
  }
}
