// Copyright (C) 2009 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.
//
// This code is based heavily on Robert Harder's <rob@iharder.net>
// public domain Base64 class, version 2.1.
//

package com.google.gerrit.httpd;

/** Base64 encoder which uses a language safe within HTTP cookies. */
class CookieBase64 {
  private static final char[] enc;

  static {
    enc = new char[64];
    int o = 0;
    o = fill(enc, o, 'a', 'z');
    o = fill(enc, o, 'A', 'Z');
    o = fill(enc, o, '0', '9');
    enc[o++] = '-';
    enc[o] = '.';
  }

  private static int fill(final char[] out, int o, final char f, final int l) {
    for (char c = f; c <= l; c++) {
      out[o++] = c;
    }
    return o;
  }

  static String encode(final byte[] in) {
    final StringBuilder out = new StringBuilder(in.length * 4 / 3);
    final int len2 = in.length - 2;
    int d = 0;
    for (; d < len2; d += 3) {
      encode3to4(out, in, d, 3);
    }
    if (d < in.length) {
      encode3to4(out, in, d, in.length - d);
    }
    return out.toString();
  }

  private static void encode3to4(
      final StringBuilder out, final byte[] in, final int inOffset, final int numSigBytes) {
    //           1         2         3
    // 01234567890123456789012345678901 Bit position
    // --------000000001111111122222222 Array position from threeBytes
    // --------|    ||    ||    ||    | Six bit groups to index ALPHABET
    //          >>18  >>12  >> 6  >> 0  Right shift necessary
    //                0x3f  0x3f  0x3f  Additional AND

    // Create buffer with zero-padding if there are only one or two
    // significant bytes passed in the array.
    // We have to shift left 24 in order to flush out the 1's that appear
    // when Java treats a value as negative that is cast from a byte to an int.
    //
    int inBuff =
        (numSigBytes > 0 ? ((in[inOffset] << 24) >>> 8) : 0)
            | (numSigBytes > 1 ? ((in[inOffset + 1] << 24) >>> 16) : 0)
            | (numSigBytes > 2 ? ((in[inOffset + 2] << 24) >>> 24) : 0);

    switch (numSigBytes) {
      case 3:
        out.append(enc[(inBuff >>> 18)]);
        out.append(enc[(inBuff >>> 12) & 0x3f]);
        out.append(enc[(inBuff >>> 6) & 0x3f]);
        out.append(enc[(inBuff) & 0x3f]);
        break;

      case 2:
        out.append(enc[(inBuff >>> 18)]);
        out.append(enc[(inBuff >>> 12) & 0x3f]);
        out.append(enc[(inBuff >>> 6) & 0x3f]);
        break;

      case 1:
        out.append(enc[(inBuff >>> 18)]);
        out.append(enc[(inBuff >>> 12) & 0x3f]);
        break;

      default:
        break;
    }
  }

  private CookieBase64() {}
}
