/**
 * 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.twitter.distributedlog;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;

import com.google.common.base.Preconditions;

import com.twitter.distributedlog.exceptions.InvalidEnvelopedEntryException;
import org.apache.bookkeeper.stats.Counter;
import org.apache.bookkeeper.stats.OpStatsLogger;
import org.apache.bookkeeper.stats.StatsLogger;

import com.twitter.distributedlog.annotations.DistributedLogAnnotations.Compression;
import com.twitter.distributedlog.io.CompressionCodec;
import com.twitter.distributedlog.io.CompressionUtils;
import com.twitter.distributedlog.util.BitMaskUtils;

/**
 * An enveloped entry written to BookKeeper.
 *
 * Data type in brackets. Interpretation should be on the basis of data types and not individual
 * bytes to honor Endianness.
 *
 * Entry Structure:
 * ---------------
 * Bytes 0                                  : Version (Byte)
 * Bytes 1 - (DATA = 1+Header.length-1)     : Header (Integer)
 * Bytes DATA - DATA+3                      : Payload Length (Integer)
 * BYTES DATA+4 - DATA+4+payload.length-1   : Payload (Byte[])
 *
 * V1 Header Structure: // Offsets relative to the start of the header.
 * -------------------
 * Bytes 0 - 3                              : Flags (Integer)
 * Bytes 4 - 7                              : Original payload size before compression (Integer)
 *
 *      Flags: // 32 Bits
 *      -----
 *      0 ... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 *                                      |_|
 *                                       |
 *                               Compression Type
 *
 *      Compression Type: // 2 Bits (Least significant)
 *      ----------------
 *      00      : No Compression
 *      01      : LZ4 Compression
 *      10      : Unused
 *      11      : Unused
 */
public class EnvelopedEntry {

    public static final int VERSION_LENGTH = 1; // One byte long
    public static final byte VERSION_ONE = 1;

    public static final byte LOWEST_SUPPORTED_VERSION = VERSION_ONE;
    public static final byte HIGHEST_SUPPORTED_VERSION = VERSION_ONE;
    public static final byte CURRENT_VERSION = VERSION_ONE;

    private final OpStatsLogger compressionStat;
    private final OpStatsLogger decompressionStat;
    private final Counter compressedEntryBytes;
    private final Counter decompressedEntryBytes;
    private final byte version;

    private Header header = new Header();
    private Payload payloadCompressed = new Payload();
    private Payload payloadDecompressed = new Payload();

    public EnvelopedEntry(byte version,
                          StatsLogger statsLogger) throws InvalidEnvelopedEntryException {
        Preconditions.checkNotNull(statsLogger);
        if (version < LOWEST_SUPPORTED_VERSION || version > HIGHEST_SUPPORTED_VERSION) {
            throw new InvalidEnvelopedEntryException("Invalid enveloped entry version " + version + ", expected to be in [ "
                    + LOWEST_SUPPORTED_VERSION + " ~ " + HIGHEST_SUPPORTED_VERSION + " ]");
        }
        this.version = version;
        this.compressionStat = statsLogger.getOpStatsLogger("compression_time");
        this.decompressionStat = statsLogger.getOpStatsLogger("decompression_time");
        this.compressedEntryBytes = statsLogger.getCounter("compressed_bytes");
        this.decompressedEntryBytes = statsLogger.getCounter("decompressed_bytes");
    }

    /**
     * @param statsLogger
     *          Used for getting stats for (de)compression time
     * @param compressionType
     *          The compression type to use
     * @param decompressed
     *          The decompressed payload
     *          NOTE: The size of the byte array passed as the decompressed payload can be larger
     *                than the actual contents to be compressed.
     */
    public EnvelopedEntry(byte version,
                          CompressionCodec.Type compressionType,
                          byte[] decompressed,
                          int length,
                          StatsLogger statsLogger)
            throws InvalidEnvelopedEntryException {
        this(version, statsLogger);
        Preconditions.checkNotNull(compressionType);
        Preconditions.checkNotNull(decompressed);
        Preconditions.checkArgument(length >= 0, "Invalid bytes length " + length);

        this.header = new Header(compressionType, length);
        this.payloadDecompressed = new Payload(length, decompressed);
    }

    private boolean isReady() {
        return (header.ready && payloadDecompressed.ready);
    }

    @Compression
    public void writeFully(DataOutputStream out) throws IOException {
        Preconditions.checkNotNull(out);
        if (!isReady()) {
            throw new IOException("Entry not writable");
        }
        // Version
        out.writeByte(version);
        // Header
        header.write(out);
        // Compress
        CompressionCodec codec = CompressionUtils.getCompressionCodec(header.compressionType);
        byte[] compressed = codec.compress(
                payloadDecompressed.payload,
                0,
                payloadDecompressed.length,
                compressionStat);
        this.payloadCompressed = new Payload(compressed.length, compressed);
        this.compressedEntryBytes.add(payloadCompressed.length);
        this.decompressedEntryBytes.add(payloadDecompressed.length);
        payloadCompressed.write(out);
    }

    @Compression
    public void readFully(DataInputStream in) throws IOException {
        Preconditions.checkNotNull(in);
        // Make sure we're reading the right versioned entry.
        byte version = in.readByte();
        if (version != this.version) {
            throw new IOException(String.format("Version mismatch while reading. Received: %d," +
                    " Required: %d", version, this.version));
        }
        header.read(in);
        payloadCompressed.read(in);
        // Decompress
        CompressionCodec codec = CompressionUtils.getCompressionCodec(header.compressionType);
        byte[] decompressed = codec.decompress(
                payloadCompressed.payload,
                0,
                payloadCompressed.length,
                header.decompressedSize,
                decompressionStat);
        this.payloadDecompressed = new Payload(decompressed.length, decompressed);
        this.compressedEntryBytes.add(payloadCompressed.length);
        this.decompressedEntryBytes.add(payloadDecompressed.length);
    }

    public byte[] getDecompressedPayload() throws IOException {
        if (!isReady()) {
            throw new IOException("Decompressed payload is not initialized");
        }
        return payloadDecompressed.payload;
    }

    public static class Header {
        public static final int COMPRESSION_CODEC_MASK = 0x3;
        public static final int COMPRESSION_CODEC_NONE = 0x0;
        public static final int COMPRESSION_CODEC_LZ4 = 0x1;

        private int flags = 0;
        private int decompressedSize = 0;
        private CompressionCodec.Type compressionType = CompressionCodec.Type.UNKNOWN;

        // Whether this struct is ready for reading/writing.
        private boolean ready = false;

        // Used while reading.
        public Header() {
        }

        public Header(CompressionCodec.Type compressionType,
                      int decompressedSize) {
            this.compressionType = compressionType;
            this.decompressedSize = decompressedSize;
            this.flags = 0;
            switch (compressionType) {
                case NONE:
                    this.flags = (int) BitMaskUtils.set(flags, COMPRESSION_CODEC_MASK,
                                                        COMPRESSION_CODEC_NONE);
                    break;
                case LZ4:
                    this.flags = (int) BitMaskUtils.set(flags, COMPRESSION_CODEC_MASK,
                                                        COMPRESSION_CODEC_LZ4);
                    break;
                default:
                    throw new RuntimeException(String.format("Unknown Compression Type: %s",
                                                             compressionType));
            }
            // This can now be written.
            this.ready = true;
        }

        private void write(DataOutputStream out) throws IOException {
            out.writeInt(flags);
            out.writeInt(decompressedSize);
        }

        private void read(DataInputStream in) throws IOException {
            this.flags = in.readInt();
            int compressionType = (int) BitMaskUtils.get(flags, COMPRESSION_CODEC_MASK);
            if (compressionType == COMPRESSION_CODEC_NONE) {
                this.compressionType = CompressionCodec.Type.NONE;
            } else if (compressionType == COMPRESSION_CODEC_LZ4) {
                this.compressionType = CompressionCodec.Type.LZ4;
            } else {
                throw new IOException(String.format("Unsupported Compression Type: %s",
                                                    compressionType));
            }
            this.decompressedSize = in.readInt();
            // Values can now be read.
            this.ready = true;
        }
    }

    public static class Payload {
        private int length = 0;
        private byte[] payload = null;

        // Whether this struct is ready for reading/writing.
        private boolean ready = false;

        // Used for reading
        Payload() {
        }

        Payload(int length, byte[] payload) {
            this.length = length;
            this.payload = payload;
            this.ready = true;
        }

        private void write(DataOutputStream out) throws IOException {
            out.writeInt(length);
            out.write(payload, 0, length);
        }

        private void read(DataInputStream in) throws IOException {
            this.length = in.readInt();
            this.payload = new byte[length];
            in.readFully(payload);
            this.ready = true;
        }
    }

    /**
     * Return an InputStream that reads from the provided InputStream, decompresses the data
     * and returns a new InputStream wrapping the underlying payload.
     *
     * Note that src is modified by this call.
     *
     * @return
     *      New Input stream with the underlying payload.
     * @throws Exception
     */
    public static InputStream fromInputStream(InputStream src,
                                              StatsLogger statsLogger) throws IOException {
        src.mark(VERSION_LENGTH);
        byte version = new DataInputStream(src).readByte();
        src.reset();
        EnvelopedEntry entry = new EnvelopedEntry(version, statsLogger);
        entry.readFully(new DataInputStream(src));
        return new ByteArrayInputStream(entry.getDecompressedPayload());
    }

}
