/**
 * 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.fs.permission;

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

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;

/**
 * Base class for parsing either chmod permissions or umask permissions.
 * Includes common code needed by either operation as implemented in
 * UmaskParser and ChmodParser classes.
 */
@InterfaceAudience.Private
@InterfaceStability.Unstable
class PermissionParser {
  protected boolean symbolic = false;
  protected short userMode;
  protected short groupMode;
  protected short othersMode;
  protected short stickyMode;
  protected char userType = '+';
  protected char groupType = '+';
  protected char othersType = '+';
  protected char stickyBitType = '+';
  
  /**
   * Begin parsing permission stored in modeStr
   * 
   * @param modeStr Permission mode, either octal or symbolic
   * @param symbolic Use-case specific symbolic pattern to match against
   * @throws IllegalArgumentException if unable to parse modeStr
   */
  public PermissionParser(String modeStr, Pattern symbolic, Pattern octal) 
       throws IllegalArgumentException {
    Matcher matcher = null;

    if ((matcher = symbolic.matcher(modeStr)).find()) {
      applyNormalPattern(modeStr, matcher);
    } else if ((matcher = octal.matcher(modeStr)).matches()) {
      applyOctalPattern(modeStr, matcher);
    } else {
      throw new IllegalArgumentException(modeStr);
    }
  }

  private void applyNormalPattern(String modeStr, Matcher matcher) {
    // Are there multiple permissions stored in one chmod?
    boolean commaSeperated = false;

    for (int i = 0; i < 1 || matcher.end() < modeStr.length(); i++) {
      if (i > 0 && (!commaSeperated || !matcher.find())) {
        throw new IllegalArgumentException(modeStr);
      }

      /*
       * groups : 1 : [ugoa]* 2 : [+-=] 3 : [rwxXt]+ 4 : [,\s]*
       */

      String str = matcher.group(2);
      char type = str.charAt(str.length() - 1);

      boolean user, group, others, stickyBit;
      user = group = others = stickyBit = false;

      for (char c : matcher.group(1).toCharArray()) {
        switch (c) {
        case 'u':
          user = true;
          break;
        case 'g':
          group = true;
          break;
        case 'o':
          others = true;
          break;
        case 'a':
          break;
        default:
          throw new RuntimeException("Unexpected");
        }
      }

      if (!(user || group || others)) { // same as specifying 'a'
        user = group = others = true;
      }

      short mode = 0;

      for (char c : matcher.group(3).toCharArray()) {
        switch (c) {
        case 'r':
          mode |= 4;
          break;
        case 'w':
          mode |= 2;
          break;
        case 'x':
          mode |= 1;
          break;
        case 'X':
          mode |= 8;
          break;
        case 't':
          stickyBit = true;
          break;
        default:
          throw new RuntimeException("Unexpected");
        }
      }

      if (user) {
        userMode = mode;
        userType = type;
      }

      if (group) {
        groupMode = mode;
        groupType = type;
      }

      if (others) {
        othersMode = mode;
        othersType = type;

        stickyMode = (short) (stickyBit ? 1 : 0);
        stickyBitType = type;
      }

      commaSeperated = matcher.group(4).contains(",");
    }
    symbolic = true;
  }

  private void applyOctalPattern(String modeStr, Matcher matcher) {
    userType = groupType = othersType = '=';

    // Check if sticky bit is specified
    String sb = matcher.group(1);
    if (!sb.isEmpty()) {
      stickyMode = Short.valueOf(sb.substring(0, 1));
      stickyBitType = '=';
    }

    String str = matcher.group(2);
    userMode = Short.valueOf(str.substring(0, 1));
    groupMode = Short.valueOf(str.substring(1, 2));
    othersMode = Short.valueOf(str.substring(2, 3));
  }

  protected int combineModes(int existing, boolean exeOk) {
    return   combineModeSegments(stickyBitType, stickyMode, 
                (existing>>>9), false) << 9 |
             combineModeSegments(userType, userMode,
                (existing>>>6)&7, exeOk) << 6 |
             combineModeSegments(groupType, groupMode,
                (existing>>>3)&7, exeOk) << 3 |
             combineModeSegments(othersType, othersMode, existing&7, exeOk);
  }
  
  protected int combineModeSegments(char type, int mode, 
                                    int existing, boolean exeOk) {
    boolean capX = false;

    if ((mode&8) != 0) { // convert X to x;
      capX = true;
      mode &= ~8;
      mode |= 1;
    }

    switch (type) {
    case '+' : mode = mode | existing; break;
    case '-' : mode = (~mode) & existing; break;
    case '=' : break;
    default  : throw new RuntimeException("Unexpected");      
    }

    // if X is specified add 'x' only if exeOk or x was already set.
    if (capX && !exeOk && (mode&1) != 0 && (existing&1) == 0) {
      mode &= ~1; // remove x
    }

    return mode;
  }
}
