/*
 * 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.carbondata.core.datastore.compression;

import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;

import org.apache.carbondata.common.logging.LogServiceFactory;

import org.apache.log4j.Logger;
import org.xerial.snappy.Snappy;
import org.xerial.snappy.SnappyNative;

public class SnappyCompressor extends AbstractCompressor {

  private static final Logger LOGGER =
      LogServiceFactory.getLogService(SnappyCompressor.class.getName());

  // snappy estimate max compressed length as 32 + source_len + source_len/6
  public static final int MAX_BYTE_TO_COMPRESS = (int)((Integer.MAX_VALUE - 32) / 7.0 * 6);

  private final transient SnappyNative snappyNative;

  public SnappyCompressor() {
    Snappy snappy = new Snappy();
    Field privateField = null;
    try {
      privateField = snappy.getClass().getDeclaredField("impl");
    } catch (NoSuchFieldException | SecurityException e) {
      throw new RuntimeException(e);
    }
    privateField.setAccessible(true);
    try {
      snappyNative = (SnappyNative) privateField.get(snappy);
    } catch (IllegalArgumentException | IllegalAccessException e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public String getName() {
    return "snappy";
  }

  @Override
  public ByteBuffer compressByte(ByteBuffer compInput) {
    int inputLength = compInput.position();
    ByteBuffer output = ByteBuffer.allocateDirect(Snappy.maxCompressedLength(inputLength));
    int outputSize;
    compInput.flip();
    try {
      outputSize = Snappy.compress(compInput, output);
    } catch (IOException e) {
      LOGGER.error(e.getMessage(), e);
      throw new RuntimeException(e);
    }
    output.limit(outputSize);
    return output;
  }

  @Override
  public ByteBuffer compressByte(byte[] unCompInput) {
    try {
      return ByteBuffer.wrap(Snappy.rawCompress(unCompInput, unCompInput.length));
    } catch (IOException e) {
      LOGGER.error(e.getMessage(), e);
      throw new RuntimeException(e);
    }
  }

  @Override
  public byte[] compressByte(byte[] unCompInput, int byteSize) {
    try {
      return Snappy.rawCompress(unCompInput, byteSize);
    } catch (IOException e) {
      LOGGER.error(e.getMessage(), e);
      throw new RuntimeException(e);
    }
  }

  @Override
  public byte[] unCompressByte(byte[] compInput) {
    try {
      return Snappy.uncompress(compInput);
    } catch (IOException e) {
      LOGGER.error(e.getMessage(), e);
      throw new RuntimeException(e);
    }
  }

  @Override
  public byte[] unCompressByte(byte[] compInput, int offset, int length) {
    int uncompressedLength = 0;
    byte[] data;
    try {
      uncompressedLength = Snappy.uncompressedLength(compInput, offset, length);
      data = new byte[uncompressedLength];
      snappyNative.rawUncompress(compInput, offset, length, data, 0);
    } catch (IOException e) {
      LOGGER.error(e.getMessage(), e);
      throw new RuntimeException(e);
    }
    return data;
  }

  @Override
  public short[] unCompressShort(byte[] compInput, int offset, int length) {
    try {
      return Snappy.uncompressShortArray(compInput, offset, length);
    } catch (IOException e) {
      LOGGER.error(e.getMessage(), e);
      throw new RuntimeException(e);
    }
  }

  @Override
  public int[] unCompressInt(byte[] compInput, int offset, int length) {
    try {
      return Snappy.uncompressIntArray(compInput, offset, length);
    } catch (IOException e) {
      LOGGER.error(e.getMessage(), e);
      throw new RuntimeException(e);
    }
  }

  @Override
  public long[] unCompressLong(byte[] compInput, int offset, int length) {
    try {
      return Snappy.uncompressLongArray(compInput, offset, length);
    } catch (IOException e) {
      LOGGER.error(e.getMessage(), e);
      throw new RuntimeException(e);
    }
  }

  @Override
  public float[] unCompressFloat(byte[] compInput, int offset, int length) {
    try {
      return Snappy.uncompressFloatArray(compInput, offset, length);
    } catch (IOException e) {
      LOGGER.error(e.getMessage(), e);
      throw new RuntimeException(e);
    }
  }

  @Override
  public double[] unCompressDouble(byte[] compInput, int offset, int length) {
    try {
      int uncompressedLength = Snappy.uncompressedLength(compInput, offset, length);
      double[] result = new double[uncompressedLength / 8];
      snappyNative.rawUncompress(compInput, offset, length, result, 0);
      return result;
    } catch (IOException e) {
      LOGGER.error(e.getMessage(), e);
      throw new RuntimeException(e);
    }
  }

  @Override
  public long rawCompress(long inputAddress, int inputSize, long outputAddress) throws IOException {
    return snappyNative.rawCompress(inputAddress, inputSize, outputAddress);
  }

  @Override
  public long rawUncompress(byte[] input, byte[] output) throws IOException {
    return snappyNative.rawUncompress(input, 0, input.length, output, 0);
  }

  @Override
  public long maxCompressedLength(long inputSize) {
    return snappyNative.maxCompressedLength((int) inputSize);
  }

  @Override
  public boolean supportUnsafe() {
    return true;
  }

  @Override
  public int unCompressedLength(byte[] data, int offset, int length) {
    try {
      return Snappy.uncompressedLength(data, offset, length);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public int rawUncompress(byte[] data, int offset, int length, byte[] output) {
    try {
      return Snappy.rawUncompress(data, offset, length, output, 0);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public boolean supportReusableBuffer() {
    return true;
  }
}
