// Copyright (C) 2019 The Android Open Source Project
//
// Licensed 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 com.google.gerrit.entities;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

public class KeyUtil {
  private static final char[] hexc = {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
  };
  private static final char safe[];
  private static final byte hexb[];

  static {
    safe = new char[256];
    safe['-'] = '-';
    safe['_'] = '_';
    safe['.'] = '.';
    safe['!'] = '!';
    safe['~'] = '~';
    safe['*'] = '*';
    safe['\''] = '\'';
    safe['('] = '(';
    safe[')'] = ')';
    safe['/'] = '/';
    safe[' '] = '+';
    for (char c = '0'; c <= '9'; c++) safe[c] = c;
    for (char c = 'A'; c <= 'Z'; c++) safe[c] = c;
    for (char c = 'a'; c <= 'z'; c++) safe[c] = c;

    hexb = new byte['f' + 1];
    Arrays.fill(hexb, (byte) -1);
    for (char i = '0'; i <= '9'; i++) hexb[i] = (byte) (i - '0');
    for (char i = 'A'; i <= 'F'; i++) hexb[i] = (byte) ((i - 'A') + 10);
    for (char i = 'a'; i <= 'f'; i++) hexb[i] = (byte) ((i - 'a') + 10);
  }

  public static String encode(final String e) {
    final byte[] b;
    try {
      b = e.getBytes("UTF-8");
    } catch (UnsupportedEncodingException e1) {
      throw new RuntimeException("No UTF-8 support", e1);
    }

    final StringBuilder r = new StringBuilder(b.length);
    for (int i = 0; i < b.length; i++) {
      final int c = b[i] & 0xff;
      final char s = safe[c];
      if (s == 0) {
        r.append('%');
        r.append(hexc[c >> 4]);
        r.append(hexc[c & 15]);
      } else {
        r.append(s);
      }
    }
    return r.toString();
  }

  public static String decode(final String e) {
    if (e.indexOf('%') < 0) {
      return e.replace('+', ' ');
    }

    final byte[] b = new byte[e.length()];
    int bPtr = 0;
    try {
      for (int i = 0; i < e.length(); ) {
        final char c = e.charAt(i);
        if (c == '%' && i + 2 < e.length()) {
          final int v = (hexb[e.charAt(i + 1)] << 4) | hexb[e.charAt(i + 2)];
          if (v < 0) {
            throw new IllegalArgumentException(e.substring(i, i + 3));
          }
          b[bPtr++] = (byte) v;
          i += 3;
        } else if (c == '+') {
          b[bPtr++] = ' ';
          i++;
        } else {
          b[bPtr++] = (byte) c;
          i++;
        }
      }
    } catch (ArrayIndexOutOfBoundsException err) {
      throw new IllegalArgumentException("Bad encoding" + e, err);
    }
    try {
      return new String(b, 0, bPtr, "UTF-8");
    } catch (UnsupportedEncodingException e1) {
      throw new RuntimeException("No UTF-8 support", e1);
    }
  }
}
