/**
 * 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 com.intel.chimera.stream;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.WritableByteChannel;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.util.Properties;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.ShortBufferException;

import com.google.common.base.Preconditions;
import com.intel.chimera.cipher.Cipher;
import com.intel.chimera.cipher.CipherTransformation;
import com.intel.chimera.output.ChannelOutput;
import com.intel.chimera.output.Output;
import com.intel.chimera.output.StreamOutput;
import com.intel.chimera.utils.Utils;

/**
 * CryptoOutputStream encrypts data. It is not thread-safe. AES CTR mode is
 * required in order to ensure that the plain text and cipher text have a 1:1
 * mapping. The encryption is buffer based. The key points of the encryption are
 * (1) calculating counter and (2) padding through stream position.
 * <p/>
 * counter = base + pos/(algorithm blocksize);
 * padding = pos%(algorithm blocksize);
 * <p/>
 * The underlying stream offset is maintained as state.
 */
public class CryptoOutputStream extends OutputStream implements
    WritableByteChannel {
  private Output output;
  private final Cipher cipher;
  private final int bufferSize;

  private final byte[] key;
  private final byte[] initIV;
  private byte[] iv;

  private long streamOffset = 0; // Underlying stream offset.
  private boolean cipherReset = false;

  private final byte[] oneByteBuf = new byte[1];

  /**
   * Input data buffer. The data starts at inBuffer.position() and ends at
   * inBuffer.limit().
   */
  private ByteBuffer inBuffer;

  /**
   * Encrypted data buffer. The data starts at outBuffer.position() and ends at
   * outBuffer.limit();
   */
  private ByteBuffer outBuffer;

  /**
   * Padding = pos%(algorithm blocksize); Padding is put into {@link #inBuffer}
   * before any other data goes in. The purpose of padding is to put input data
   * at proper position.
   */
  private byte padding;
  private boolean closed;

  public CryptoOutputStream(CipherTransformation transformation,
      Properties props, OutputStream out, byte[] key, byte[] iv)
      throws IOException {
    this(out, Utils.getCipherInstance(transformation, props),
        Utils.getBufferSize(props), key, iv);
  }

  public CryptoOutputStream(CipherTransformation transformation,
      Properties props, WritableByteChannel out, byte[] key, byte[] iv)
      throws IOException {
    this(out, Utils.getCipherInstance(transformation, props),
        Utils.getBufferSize(props), key, iv);
  }

  public CryptoOutputStream(OutputStream out, Cipher cipher,
      int bufferSize, byte[] key, byte[] iv) throws IOException {
    this(new StreamOutput(out, bufferSize), cipher, bufferSize, key, iv);
  }

  public CryptoOutputStream(WritableByteChannel channel, Cipher cipher,
      int bufferSize, byte[] key, byte[] iv) throws IOException {
    this(new ChannelOutput(channel), cipher, bufferSize, key, iv);
  }

  public CryptoOutputStream(Output output, Cipher cipher,
      int bufferSize, byte[] key, byte[] iv)
      throws IOException {
    this(output, cipher, bufferSize, key, iv, 0);
  }

  protected CryptoOutputStream(Output output, Cipher cipher,
      int bufferSize, byte[] key, byte[] iv, long streamOffset)
      throws IOException {
    Utils.checkStreamCipher(cipher);

    this.output = output;
    this.bufferSize = Utils.checkBufferSize(cipher, bufferSize);
    this.cipher = cipher;
    this.key = key.clone();
    this.initIV = iv.clone();
    this.iv = iv.clone();
    inBuffer = ByteBuffer.allocateDirect(this.bufferSize);
    outBuffer = ByteBuffer.allocateDirect(this.bufferSize);
    this.streamOffset = streamOffset;

    resetCipher();
  }

  /**
   * Encryption is buffer based.
   * If there is enough room in {@link #inBuffer}, then write to this buffer.
   * If {@link #inBuffer} is full, then do encryption and write data to the
   * underlying stream.
   * @param b the data.
   * @param off the start offset in the data.
   * @param len the number of bytes to write.
   * @throws IOException
   */
  @Override
  public void write(byte[] b, int off, int len) throws IOException {
    checkStream();
    if (b == null) {
      throw new NullPointerException();
    } else if (off < 0 || len < 0 || off > b.length ||
        len > b.length - off) {
      throw new IndexOutOfBoundsException();
    }
    while (len > 0) {
      final int remaining = inBuffer.remaining();
      if (len < remaining) {
        inBuffer.put(b, off, len);
        len = 0;
      } else {
        inBuffer.put(b, off, remaining);
        off += remaining;
        len -= remaining;
        encrypt();
      }
    }
  }

  @Override
  public void close() throws IOException {
    if (closed) {
      return;
    }

    try {
      encrypt();
      output.close();
      freeBuffers();
      cipher.close();
      super.close();
    } finally {
      closed = true;
    }
  }

  /**
   * To flush, we need to encrypt the data in the buffer and write to the
   * underlying stream, then do the flush.
   */
  @Override
  public void flush() throws IOException {
    checkStream();
    encrypt();
    output.flush();
    super.flush();
  }

  @Override
  public void write(int b) throws IOException {
    oneByteBuf[0] = (byte)(b & 0xff);
    write(oneByteBuf, 0, oneByteBuf.length);
  }

  @Override
  public boolean isOpen() {
    return !closed;
  }

  @Override
  public int write(ByteBuffer src) throws IOException {
    checkStream();
    final int len = src.remaining();
    int remaining = len;
    while (remaining > 0) {
      final int space = inBuffer.remaining();
      if (remaining < space) {
        inBuffer.put(src);
        remaining = 0;
      } else {
        // to void copy twice, we set the limit to copy directly
        final int oldLimit = src.limit();
        final int newLimit = src.position() + space;
        src.limit(newLimit);

        inBuffer.put(src);

        // restore the old limit
        src.limit(oldLimit);

        remaining -= space;
        encrypt();
      }
    }

    return len;
  }

  /**
   * Do the encryption, input is {@link #inBuffer} and output is
   * {@link #outBuffer}.
   */
  private void encrypt() throws IOException {
    Preconditions.checkState(inBuffer.position() >= padding);
    if (inBuffer.position() == padding) {
      // There is no real data in the inBuffer.
      return;
    }

    inBuffer.flip();
    outBuffer.clear();
    encryptBuffer(outBuffer);
    inBuffer.clear();
    outBuffer.flip();

    if (padding > 0) {
      /*
       * The plain text and cipher text have a 1:1 mapping, they start at the
       * same position.
       */
      outBuffer.position(padding);
      padding = 0;
    }

    final int len = output.write(outBuffer);
    streamOffset += len;
    if (cipherReset) {
      /*
       * This code is generally not executed since the encryptor usually
       * maintains encryption context (e.g. the counter) internally. However,
       * some implementations can't maintain context so a re-init is necessary
       * after each encryption call.
       */
      resetCipher();
    }
  }

  /** Reset the {@link #cipher}: calculate counter and {@link #padding}. */
  private void resetCipher() throws IOException {
    final long counter =
        streamOffset / cipher.getTransformation().getAlgorithmBlockSize();
    padding =
        (byte)(streamOffset % cipher.getTransformation().getAlgorithmBlockSize());
    inBuffer.position(padding); // Set proper position for input data.

    Utils.calculateIV(initIV, counter, iv);
    try {
      cipher.init(Cipher.ENCRYPT_MODE, key, iv);
    } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
      throw new IOException(e);
    }
    cipherReset = false;
  }

  private void encryptBuffer(ByteBuffer out)
      throws IOException {
    int inputSize = inBuffer.remaining();
    try {
      int n = cipher.update(inBuffer, out);
      if (n < inputSize) {
        /**
         * Typically code will not get here. Cipher#update will consume all
         * input data and put result in outBuffer.
         * Cipher#doFinal will reset the cipher context.
         */
        cipher.doFinal(inBuffer, out);
        cipherReset = true;
      }
    } catch (ShortBufferException | BadPaddingException
        | IllegalBlockSizeException e) {
      throw new IOException(e);
    }
  }

  private void checkStream() throws IOException {
    if (closed) {
      throw new IOException("Stream closed");
    }
  }

  /** Forcibly free the direct buffers. */
  private void freeBuffers() {
    Utils.freeDirectBuffer(inBuffer);
    Utils.freeDirectBuffer(outBuffer);
  }
}
