/**
 * 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.hadoop.io.erasurecode.rawcoder;

import org.apache.hadoop.HadoopIllegalArgumentException;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.io.erasurecode.ECChunk;

import java.nio.ByteBuffer;
import java.util.Arrays;

/**
 * Helpful utilities for implementing some raw erasure coders.
 */
@InterfaceAudience.Private
final class CoderUtil {

  private CoderUtil() {
    // No called
  }

  private static byte[] emptyChunk = new byte[4096];

  /**
   * Make sure to return an empty chunk buffer for the desired length.
   * @param leastLength
   * @return empty chunk of zero bytes
   */
  static byte[] getEmptyChunk(int leastLength) {
    if (emptyChunk.length >= leastLength) {
      return emptyChunk; // In most time
    }

    synchronized (CoderUtil.class) {
      emptyChunk = new byte[leastLength];
    }

    return emptyChunk;
  }

  /**
   * Ensure a buffer filled with ZERO bytes from current readable/writable
   * position.
   * @param buffer a buffer ready to read / write certain size bytes
   * @return the buffer itself, with ZERO bytes written, the position and limit
   *         are not changed after the call
   */
  static ByteBuffer resetBuffer(ByteBuffer buffer, int len) {
    int pos = buffer.position();
    buffer.put(getEmptyChunk(len), 0, len);
    buffer.position(pos);

    return buffer;
  }

  /**
   * Ensure the buffer (either input or output) ready to read or write with ZERO
   * bytes fully in specified length of len.
   * @param buffer bytes array buffer
   * @return the buffer itself
   */
  static byte[] resetBuffer(byte[] buffer, int offset, int len) {
    byte[] empty = getEmptyChunk(len);
    System.arraycopy(empty, 0, buffer, offset, len);

    return buffer;
  }

  /**
   * Initialize the output buffers with ZERO bytes.
   */
  static void resetOutputBuffers(ByteBuffer[] buffers, int dataLen) {
    for (ByteBuffer buffer : buffers) {
      resetBuffer(buffer, dataLen);
    }
  }

  /**
   * Initialize the output buffers with ZERO bytes.
   */
  static void resetOutputBuffers(byte[][] buffers, int[] offsets,
                                 int dataLen) {
    for (int i = 0; i < buffers.length; i++) {
      resetBuffer(buffers[i], offsets[i], dataLen);
    }
  }

  /**
   * Convert an array of this chunks to an array of ByteBuffers
   * @param chunks chunks to convertToByteArrayState into buffers
   * @return an array of ByteBuffers
   */
  static ByteBuffer[] toBuffers(ECChunk[] chunks) {
    ByteBuffer[] buffers = new ByteBuffer[chunks.length];

    ECChunk chunk;
    for (int i = 0; i < chunks.length; i++) {
      chunk = chunks[i];
      if (chunk == null) {
        buffers[i] = null;
      } else {
        buffers[i] = chunk.getBuffer();
      }
    }

    return buffers;
  }

  /**
   * Clone an input bytes array as direct ByteBuffer.
   */
  static ByteBuffer cloneAsDirectByteBuffer(byte[] input, int offset, int len) {
    if (input == null) { // an input can be null, if erased or not to read
      return null;
    }

    ByteBuffer directBuffer = ByteBuffer.allocateDirect(len);
    directBuffer.put(input, offset, len);
    directBuffer.flip();
    return directBuffer;
  }

  /**
   * Get indexes array for items marked as null, either erased or
   * not to read.
   * @return indexes array
   */
  static <T> int[] getNullIndexes(T[] inputs) {
    int[] nullIndexes = new int[inputs.length];
    int idx = 0;
    for (int i = 0; i < inputs.length; i++) {
      if (inputs[i] == null) {
        nullIndexes[idx++] = i;
      }
    }

    return Arrays.copyOf(nullIndexes, idx);
  }

  /**
   * Find the valid input from all the inputs.
   * @param inputs input buffers to look for valid input
   * @return the first valid input
   */
  static <T> T findFirstValidInput(T[] inputs) {
    for (T input : inputs) {
      if (input != null) {
        return input;
      }
    }

    throw new HadoopIllegalArgumentException(
        "Invalid inputs are found, all being null");
  }

  /**
   * Picking up indexes of valid inputs.
   * @param inputs decoding input buffers
   * @param <T>
   */
  static <T> int[] getValidIndexes(T[] inputs) {
    int[] validIndexes = new int[inputs.length];
    int idx = 0;
    for (int i = 0; i < inputs.length; i++) {
      if (inputs[i] != null) {
        validIndexes[idx++] = i;
      }
    }

    return Arrays.copyOf(validIndexes, idx);
  }
}
