/**
 * 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_last_n",
             value = "masks all but last n characters of the value",
             extended = "Examples:\n "
                      + "  mask_show_last_n(ccn, 8)\n "
                      + "  mask_show_last_n(ccn, 8, 'x', 'x', 'x')\n "
                      + "Arguments:\n "
                      + "  mask_show_last_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 RangerUdfMaskShowLastN extends RangerBaseUdf {
  public static final String UDF_NAME = "mask_show_last_n";

  public RangerUdfMaskShowLastN() {
    super(new MaskShowLastNTransformer(), UDF_NAME);
  }
}

class MaskShowLastNTransformer extends MaskTransformer {
  int charCount = 4;

  public MaskShowLastNTransformer() {
    super();
  }

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

    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());
    final int           endIdx = value.length() - charCount;

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

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

    return ret.toString();
  }

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

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

    byte ret = 0;
    int  pos = 1;
    for(int i = 0; val != 0; i++) {
      if(i >= charCount) { // 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;
    }

    short ret = 0;
    int   pos = 1;
    for(int i = 0; val != 0; i++) {
      if(i >= charCount) { // 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;
    }

    int ret = 0;
    int pos = 1;
    for(int i = 0; val != 0; i++) {
      if(i >= charCount) { // 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;
    }

    long ret = 0;
    long pos = 1;
    for(int i = 0; val != 0; i++) {
      if(i >= charCount) { // 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;
  }
}
