/**
 * 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.hadoop.security.authentication.util;


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.google.common.annotations.VisibleForTesting;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * This class implements parsing and handling of Kerberos principal names. In
 * particular, it splits them apart and translates them down into local
 * operating system names.
 */
@SuppressWarnings("all")
@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
@InterfaceStability.Evolving
public class KerberosName {
  private static final Logger LOG = LoggerFactory.getLogger(KerberosName.class);

  /** The first component of the name */
  private final String serviceName;
  /** The second component of the name. It may be null. */
  private final String hostName;
  /** The realm of the name. */
  private final String realm;

  /**
   * A pattern that matches a Kerberos name with at most 2 components.
   */
  private static final Pattern nameParser =
      Pattern.compile("([^/@]+)(/([^/@]+))?(@([^/@]+))?");

  /**
   * A pattern that matches a string with out '$' and then a single
   * parameter with $n.
   */
  private static Pattern parameterPattern =
    Pattern.compile("([^$]*)(\\$(\\d*))?");

  /**
   * A pattern for parsing a auth_to_local rule.
   */
  private static final Pattern ruleParser =
    Pattern.compile("\\s*((DEFAULT)|(RULE:\\[(\\d*):([^\\]]*)](\\(([^)]*)\\))?"+
                    "(s/([^/]*)/([^/]*)/(g)?)?))/?(L)?");

  /**
   * A pattern that recognizes simple/non-simple names.
   */
  private static final Pattern nonSimplePattern = Pattern.compile("[/@]");

  /**
   * The list of translation rules.
   */
  private static List<Rule> rules;

  private static String defaultRealm;

  static {
    try {
      defaultRealm = KerberosUtil.getDefaultRealm();
    } catch (Exception ke) {
        LOG.debug("Kerberos krb5 configuration not found, setting default realm to empty");
        defaultRealm="";
    }
  }

  @VisibleForTesting
  public static void resetDefaultRealm() {
    try {
      defaultRealm = KerberosUtil.getDefaultRealm();
    } catch (Exception ke) {
      LOG.debug("resetting default realm failed, "
          + "current default realm will still be used.", ke);
    }
  }

  /**
   * Create a name from the full Kerberos principal name.
   * @param name full Kerberos principal name.
   */
  public KerberosName(String name) {
    Matcher match = nameParser.matcher(name);
    if (!match.matches()) {
      if (name.contains("@")) {
        throw new IllegalArgumentException("Malformed Kerberos name: " + name);
      } else {
        serviceName = name;
        hostName = null;
        realm = null;
      }
    } else {
      serviceName = match.group(1);
      hostName = match.group(3);
      realm = match.group(5);
    }
  }

  /**
   * Get the configured default realm.
   * @return the default realm from the krb5.conf
   */
  public String getDefaultRealm() {
    return defaultRealm;
  }

  /**
   * Put the name back together from the parts.
   */
  @Override
  public String toString() {
    StringBuilder result = new StringBuilder();
    result.append(serviceName);
    if (hostName != null) {
      result.append('/');
      result.append(hostName);
    }
    if (realm != null) {
      result.append('@');
      result.append(realm);
    }
    return result.toString();
  }

  /**
   * Get the first component of the name.
   * @return the first section of the Kerberos principal name
   */
  public String getServiceName() {
    return serviceName;
  }

  /**
   * Get the second component of the name.
   * @return the second section of the Kerberos principal name, and may be null
   */
  public String getHostName() {
    return hostName;
  }

  /**
   * Get the realm of the name.
   * @return the realm of the name, may be null
   */
  public String getRealm() {
    return realm;
  }

  /**
   * An encoding of a rule for translating kerberos names.
   */
  private static class Rule {
    private final boolean isDefault;
    private final int numOfComponents;
    private final String format;
    private final Pattern match;
    private final Pattern fromPattern;
    private final String toPattern;
    private final boolean repeat;
    private final boolean toLowerCase;

    Rule() {
      isDefault = true;
      numOfComponents = 0;
      format = null;
      match = null;
      fromPattern = null;
      toPattern = null;
      repeat = false;
      toLowerCase = false;
    }

    Rule(int numOfComponents, String format, String match, String fromPattern,
         String toPattern, boolean repeat, boolean toLowerCase) {
      isDefault = false;
      this.numOfComponents = numOfComponents;
      this.format = format;
      this.match = match == null ? null : Pattern.compile(match);
      this.fromPattern =
        fromPattern == null ? null : Pattern.compile(fromPattern);
      this.toPattern = toPattern;
      this.repeat = repeat;
      this.toLowerCase = toLowerCase;
    }

    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder();
      if (isDefault) {
        buf.append("DEFAULT");
      } else {
        buf.append("RULE:[");
        buf.append(numOfComponents);
        buf.append(':');
        buf.append(format);
        buf.append(']');
        if (match != null) {
          buf.append('(');
          buf.append(match);
          buf.append(')');
        }
        if (fromPattern != null) {
          buf.append("s/");
          buf.append(fromPattern);
          buf.append('/');
          buf.append(toPattern);
          buf.append('/');
          if (repeat) {
            buf.append('g');
          }
        }
        if (toLowerCase) {
          buf.append("/L");
        }
      }
      return buf.toString();
    }

    /**
     * Replace the numbered parameters of the form $n where n is from 1 to
     * the length of params. Normal text is copied directly and $n is replaced
     * by the corresponding parameter.
     * @param format the string to replace parameters again
     * @param params the list of parameters
     * @return the generated string with the parameter references replaced.
     * @throws BadFormatString
     */
    static String replaceParameters(String format,
                                    String[] params) throws BadFormatString {
      Matcher match = parameterPattern.matcher(format);
      int start = 0;
      StringBuilder result = new StringBuilder();
      while (start < format.length() && match.find(start)) {
        result.append(match.group(1));
        String paramNum = match.group(3);
        if (paramNum != null) {
          try {
            int num = Integer.parseInt(paramNum);
            if (num < 0 || num > params.length) {
              throw new BadFormatString("index " + num + " from " + format +
                                        " is outside of the valid range 0 to " +
                                        (params.length - 1));
            }
            result.append(params[num]);
          } catch (NumberFormatException nfe) {
            throw new BadFormatString("bad format in username mapping in " +
                                      paramNum, nfe);
          }

        }
        start = match.end();
      }
      return result.toString();
    }

    /**
     * Replace the matches of the from pattern in the base string with the value
     * of the to string.
     * @param base the string to transform
     * @param from the pattern to look for in the base string
     * @param to the string to replace matches of the pattern with
     * @param repeat whether the substitution should be repeated
     * @return
     */
    static String replaceSubstitution(String base, Pattern from, String to,
                                      boolean repeat) {
      Matcher match = from.matcher(base);
      if (repeat) {
        return match.replaceAll(to);
      } else {
        return match.replaceFirst(to);
      }
    }

    /**
     * Try to apply this rule to the given name represented as a parameter
     * array.
     * @param params first element is the realm, second and later elements are
     *        are the components of the name "a/b@FOO" -> {"FOO", "a", "b"}
     * @return the short name if this rule applies or null
     * @throws IOException throws if something is wrong with the rules
     */
    String apply(String[] params) throws IOException {
      String result = null;
      if (isDefault) {
        if (defaultRealm.equals(params[0])) {
          result = params[1];
        }
      } else if (params.length - 1 == numOfComponents) {
        String base = replaceParameters(format, params);
        if (match == null || match.matcher(base).matches()) {
          if (fromPattern == null) {
            result = base;
          } else {
            result = replaceSubstitution(base, fromPattern, toPattern,  repeat);
          }
        }
      }
      if (result != null && nonSimplePattern.matcher(result).find()) {
        throw new NoMatchingRule("Non-simple name " + result +
                                 " after auth_to_local rule " + this);
      }
      if (toLowerCase && result != null) {
        result = result.toLowerCase(Locale.ENGLISH);
      }
      return result;
    }
  }

  static List<Rule> parseRules(String rules) {
    List<Rule> result = new ArrayList<Rule>();
    String remaining = rules.trim();
    while (remaining.length() > 0) {
      Matcher matcher = ruleParser.matcher(remaining);
      if (!matcher.lookingAt()) {
        throw new IllegalArgumentException("Invalid rule: " + remaining);
      }
      if (matcher.group(2) != null) {
        result.add(new Rule());
      } else {
        result.add(new Rule(Integer.parseInt(matcher.group(4)),
                            matcher.group(5),
                            matcher.group(7),
                            matcher.group(9),
                            matcher.group(10),
                            "g".equals(matcher.group(11)),
                            "L".equals(matcher.group(12))));
      }
      remaining = remaining.substring(matcher.end());
    }
    return result;
  }

  @SuppressWarnings("serial")
  public static class BadFormatString extends IOException {
    BadFormatString(String msg) {
      super(msg);
    }
    BadFormatString(String msg, Throwable err) {
      super(msg, err);
    }
  }

  @SuppressWarnings("serial")
  public static class NoMatchingRule extends IOException {
    NoMatchingRule(String msg) {
      super(msg);
    }
  }

  /**
   * Get the translation of the principal name into an operating system
   * user name.
   * @return the short name
   * @throws IOException throws if something is wrong with the rules
   */
  public String getShortName() throws IOException {
    String[] params;
    if (hostName == null) {
      // if it is already simple, just return it
      if (realm == null) {
        return serviceName;
      }
      params = new String[]{realm, serviceName};
    } else {
      params = new String[]{realm, serviceName, hostName};
    }
    for(Rule r: rules) {
      String result = r.apply(params);
      if (result != null) {
        return result;
      }
    }
    throw new NoMatchingRule("No rules applied to " + toString());
  }

  /**
   * Set the rules.
   * @param ruleString the rules string.
   */
  public static void setRules(String ruleString) {
    rules = (ruleString != null) ? parseRules(ruleString) : null;
  }

  /**
   * Get the rules.
   * @return String of configured rules, or null if not yet configured
   */
  public static String getRules() {
    String ruleString = null;
    if (rules != null) {
      StringBuilder sb = new StringBuilder();
      for (Rule rule : rules) {
        sb.append(rule.toString()).append("\n");
      }
      ruleString = sb.toString().trim();
    }
    return ruleString;
  }

  /**
   * Indicates if the name rules have been set.
   *
   * @return if the name rules have been set.
   */
  public static boolean hasRulesBeenSet() {
    return rules != null;
  }

  static void printRules() throws IOException {
    int i = 0;
    for(Rule r: rules) {
      System.out.println(++i + " " + r);
    }
  }

}
