/**
 * 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.ranger.authorization.hive.udf;

import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;


@Description(name = "mask_show_first_n",
             value = "masks all but first n characters of the value",
             extended = "Examples:\n "
                      + "  mask_show_first_n(ccn, 8)\n "
                      + "  mask_show_first_n(ccn, 8, 'x', 'x', 'x')\n "
                      + "Arguments:\n "
                      + "  mask_show_first_n(value, charCount, upperChar, lowerChar, digitChar, otherChar, numberChar)\n "
                      + "    value      - value to mask. Supported types: TINYINT, SMALLINT, INT, BIGINT, STRING, VARCHAR, CHAR\n "
                      + "    charCount  - number of characters. Default value: 4\n "
                      + "    upperChar  - character to replace upper-case characters with. Specify -1 to retain original character. Default value: 'X'\n "
                      + "    lowerChar  - character to replace lower-case characters with. Specify -1 to retain original character. Default value: 'x'\n "
                      + "    digitChar  - character to replace digit characters with. Specify -1 to retain original character. Default value: 'n'\n "
                      + "    otherChar  - character to replace all other characters with. Specify -1 to retain original character. Default value: -1\n "
                      + "    numberChar - character to replace digits in a number with. Valid values: 0-9. Default value: '1'\n "
            )
public class RangerUdfMaskShowFirstN extends RangerBaseUdf {
  public static final String UDF_NAME = "mask_show_first_n";

  public RangerUdfMaskShowFirstN() {
    super(new MaskShowFirstNTransformer(), UDF_NAME);
  }
}

class MaskShowFirstNTransformer extends MaskTransformer {
  int charCount = 4;

  public MaskShowFirstNTransformer() {
    super();
  }

  @Override
  public void init(ObjectInspector[] arguments, int argsStartIdx) {
    super.init(arguments, argsStartIdx + 1); // first argument is charCount, which is consumed here

    charCount = getIntArg(arguments, argsStartIdx, 4);

    if(charCount < 0) {
      charCount = 0;
    }
  }

  @Override
  String transform(final String value) {
    if(value.length() <= charCount) {
      return value;
    }

    final StringBuilder ret = new StringBuilder(value.length());

    for(int i = 0; i < charCount; i++) {
      ret.appendCodePoint(value.charAt(i));
    }

    for(int i = charCount; i < value.length(); i++) {
      ret.appendCodePoint(transformChar(value.charAt(i)));
    }

    return ret.toString();
  }

  @Override
  Byte transform(final Byte value) {
    byte val = value;

    if(value < 0) {
      val *= -1;
    }

    // count number of digits in the value
    int digitCount = 0;
    for(byte v = val; v != 0; v /= 10) {
      digitCount++;
    }

    // number of digits to mask from the end
    final int maskCount = digitCount - charCount;

    if(maskCount <= 0) {
      return value;
    }

    byte ret = 0;
    int  pos = 1;
    for(int i = 0; val != 0; i++) {
      if(i < maskCount) { // mask this digit
        ret += (maskedNumber * pos);
      } else { //retain this digit
        ret += ((val % 10) * pos);
      }

      val /= 10;
      pos *= 10;
    }

    if(value < 0) {
      ret *= -1;
    }

    return ret;
  }

  @Override
  Short transform(final Short value) {
    short val = value;

    if(value < 0) {
      val *= -1;
    }

    // count number of digits in the value
    int digitCount = 0;
    for(short v = val; v != 0; v /= 10) {
      digitCount++;
    }

    // number of digits to mask from the end
    final int maskCount = digitCount - charCount;

    if(maskCount <= 0) {
      return value;
    }

    short ret = 0;
    int   pos = 1;
    for(int i = 0; val != 0; i++) {
      if(i < maskCount) { // mask this digit
        ret += (maskedNumber * pos);
      } else { // retain this digit
        ret += ((val % 10) * pos);
      }

      val /= 10;
      pos *= 10;
    }

    if(value < 0) {
      ret *= -1;
    }

    return ret;
  }

  @Override
  Integer transform(final Integer value) {
    int val = value;

    if(value < 0) {
      val *= -1;
    }

    // count number of digits in the value
    int digitCount = 0;
    for(int v = val; v != 0; v /= 10) {
      digitCount++;
    }

    // number of digits to mask from the end
    final int maskCount = digitCount - charCount;

    if(maskCount <= 0) {
      return value;
    }

    int ret = 0;
    int pos = 1;
    for(int i = 0; val != 0; i++) {
      if(i < maskCount) { // mask this digit
        ret += maskedNumber * pos;
      } else { // retain this digit
        ret += ((val % 10) * pos);
      }

      val /= 10;
      pos *= 10;
    }

    if(value < 0) {
      ret *= -1;
    }

    return ret;
  }

  @Override
  Long transform(final Long value) {
    long val = value;

    if(value < 0) {
      val *= -1;
    }

    // count number of digits in the value
    int digitCount = 0;
    for(long v = val; v != 0; v /= 10) {
      digitCount++;
    }

    // number of digits to mask from the end
    final int maskCount = digitCount - charCount;

    if(maskCount <= 0) {
      return value;
    }

    long ret = 0;
    long pos = 1;
    for(int i = 0; val != 0; i++) {
      if(i < maskCount) { // mask this digit
        ret += (maskedNumber * pos);
      } else { // retain this digit
        ret += ((val % 10) * pos);
      }

      val /= 10;
      pos *= 10;
    }

    if(value < 0) {
      ret *= -1;
    }

    return ret;
  }
}
