/*
 * 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.
 *
 * Some portions of this file Copyright (c) 2004-2006 Intel Corportation
 * and licensed under the BSD license.
 */
package org.apache.hadoop.ozone.common;

import org.apache.ratis.util.Preconditions;

import java.nio.ByteBuffer;
import java.util.zip.Checksum;

/**
 * A sub-interface of {@link Checksum}
 * with a method to update checksum from a {@link ByteBuffer}.
 */
public interface ChecksumByteBuffer extends Checksum {
  /**
   * Updates the current checksum with the specified bytes in the buffer.
   * Upon return, the buffer's position will be equal to its limit.
   *
   * @param buffer the bytes to update the checksum with
   */
  void update(ByteBuffer buffer);

  @Override
  default void update(byte[] b, int off, int len) {
    update(ByteBuffer.wrap(b, off, len).asReadOnlyBuffer());
  }

  /**
   * An abstract class implementing {@link ChecksumByteBuffer}
   * with a 32-bit checksum and a lookup table.
   */
  abstract class CrcIntTable implements ChecksumByteBuffer {
    /** Current CRC value with bit-flipped. */
    private int crc;

    CrcIntTable() {
      reset();
      Preconditions.assertTrue(getTable().length == 8 * (1 << 8));
    }

    abstract int[] getTable();

    @Override
    public final long getValue() {
      return (~crc) & 0xffffffffL;
    }

    @Override
    public final void reset() {
      crc = 0xffffffff;
    }

    @Override
    public final void update(int b) {
      crc = (crc >>> 8) ^ getTable()[(((crc ^ b) << 24) >>> 24)];
    }

    @Override
    public final void update(ByteBuffer b) {
      crc = update(crc, b, getTable());
    }

    private static int update(int crc, ByteBuffer b, int[] table) {
      for(; b.remaining() > 7;) {
        final int c0 = (b.get() ^ crc) & 0xff;
        final int c1 = (b.get() ^ (crc >>>= 8)) & 0xff;
        final int c2 = (b.get() ^ (crc >>>= 8)) & 0xff;
        final int c3 = (b.get() ^ (crc >>> 8)) & 0xff;
        crc = (table[0x700 + c0] ^ table[0x600 + c1])
            ^ (table[0x500 + c2] ^ table[0x400 + c3]);

        final int c4 = b.get() & 0xff;
        final int c5 = b.get() & 0xff;
        final int c6 = b.get() & 0xff;
        final int c7 = b.get() & 0xff;

        crc ^= (table[0x300 + c4] ^ table[0x200 + c5])
            ^ (table[0x100 + c6] ^ table[c7]);
      }

      // loop unroll - duff's device style
      switch (b.remaining()) {
        case 7: crc = (crc >>> 8) ^ table[((crc ^ b.get()) & 0xff)];
        case 6: crc = (crc >>> 8) ^ table[((crc ^ b.get()) & 0xff)];
        case 5: crc = (crc >>> 8) ^ table[((crc ^ b.get()) & 0xff)];
        case 4: crc = (crc >>> 8) ^ table[((crc ^ b.get()) & 0xff)];
        case 3: crc = (crc >>> 8) ^ table[((crc ^ b.get()) & 0xff)];
        case 2: crc = (crc >>> 8) ^ table[((crc ^ b.get()) & 0xff)];
        case 1: crc = (crc >>> 8) ^ table[((crc ^ b.get()) & 0xff)];
        default: // noop
      }

      return crc;
    }
  }
}
