/*
 * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.jfr.internal;

import jdk.internal.misc.Unsafe;
import jdk.jfr.internal.consumer.RecordingInput;

/**
 * Class must reside in a package with package restriction.
 *
 * Users should not have direct access to underlying memory.
 *
 */
public final class EventWriter {
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private final static JVM jvm = JVM.getJVM();

    private long startPosition;
    private long startPositionAddress;
    private long currentPosition;
    private long maxPosition;
    private final long threadID;
    private PlatformEventType eventType;
    private int maxEventSize;
    private boolean started;
    private boolean valid;
    private boolean flushOnEnd;
    // set by the JVM, not private to avoid being optimized out
    boolean notified;

    public static EventWriter getEventWriter() {
        EventWriter ew = (EventWriter)JVM.getEventWriter();
        return ew != null ? ew : JVM.newEventWriter();
    }

    public void putBoolean(boolean i) {
        if (isValidForSize(Byte.BYTES)) {
            currentPosition += Bits.putBoolean(currentPosition, i);
        }
    }

    public void putByte(byte i) {
        if (isValidForSize(Byte.BYTES)) {
            unsafe.putByte(currentPosition, i);
            ++currentPosition;
        }
    }

    public void putChar(char v) {
        if (isValidForSize(Character.BYTES + 1)) {
            putUncheckedLong(v);
        }
    }

    private void putUncheckedChar(char v) {
        putUncheckedLong(v);
    }

    public void putShort(short v) {
        if (isValidForSize(Short.BYTES + 1)) {
            putUncheckedLong(v & 0xFFFF);
        }
    }

    public void putInt(int v) {
        if (isValidForSize(Integer.BYTES + 1)) {
            putUncheckedLong(v & 0x00000000ffffffffL);
        }
    }

    private void putUncheckedInt(int v) {
        putUncheckedLong(v & 0x00000000ffffffffL);
    }

    public void putFloat(float i) {
        if (isValidForSize(Float.BYTES)) {
            currentPosition += Bits.putFloat(currentPosition, i);
        }
    }

    public void putLong(long v) {
        if (isValidForSize(Long.BYTES + 1)) {
            putUncheckedLong(v);
        }
    }

    public void putDouble(double i) {
        if (isValidForSize(Double.BYTES)) {
            currentPosition += Bits.putDouble(currentPosition, i);
        }
    }

    public void putString(String s, StringPool pool) {
        if (s == null) {
            putByte(RecordingInput.STRING_ENCODING_NULL);
            return;
        }
        int length = s.length();
        if (length == 0) {
            putByte(RecordingInput.STRING_ENCODING_EMPTY_STRING);
            return;
        }
        if (length > StringPool.MIN_LIMIT && length < StringPool.MAX_LIMIT) {
            long l = StringPool.addString(s);
            if (l > 0) {
                putByte(RecordingInput.STRING_ENCODING_CONSTANT_POOL);
                putLong(l);
                return;
            }
        }
        putStringValue(s);
        return;
    }

    private void putStringValue(String s) {
        int length = s.length();
        if (isValidForSize(1 + 5 + 3 * length)) {
            putUncheckedByte(RecordingInput.STRING_ENCODING_CHAR_ARRAY); // 1 byte
            putUncheckedInt(length); // max 5 bytes
            for (int i = 0; i < length; i++) {
                putUncheckedChar(s.charAt(i)); // max 3 bytes
            }
        }
    }

    public void putEventThread() {
        putLong(threadID);
    }

    public void putThread(Thread athread) {
        if (athread == null) {
            putLong(0L);
        } else {
            putLong(jvm.getThreadId(athread));
        }
    }

    public void putClass(Class<?> aClass) {
        if (aClass == null) {
            putLong(0L);
        } else {
            putLong(JVM.getClassIdNonIntrinsic(aClass));
        }
    }

    public void putStackTrace() {
        if (eventType.getStackTraceEnabled()) {
            putLong(jvm.getStackTraceId(eventType.getStackTraceOffset()));
        } else {
            putLong(0L);
        }
    }

    private void reserveEventSizeField() {
        // move currentPosition Integer.Bytes offset from start position
        if (isValidForSize(Integer.BYTES)) {
            currentPosition += Integer.BYTES;
        }
    }

    private void reset() {
        currentPosition = startPosition;
        if (flushOnEnd) {
            flushOnEnd = flush();
        }
        valid = true;
        started = false;
    }

    private boolean isValidForSize(int requestedSize) {
        if (!valid) {
            return false;
        }
        if (currentPosition + requestedSize > maxPosition) {
            flushOnEnd = flush(usedSize(), requestedSize);
            // retry
            if (currentPosition + requestedSize > maxPosition) {
                Logger.log(LogTag.JFR_SYSTEM,
                           LogLevel.WARN, () ->
                               "Unable to commit. Requested size " + requestedSize + " too large");
                valid = false;
                return false;
            }
        }
        return true;
    }

    private boolean isNotified() {
        return notified;
    }

    private void resetNotified() {
        notified = false;
    }

    private int usedSize() {
        return (int) (currentPosition - startPosition);
    }

    private boolean flush() {
        return flush(usedSize(), 0);
    }

    private boolean flush(int usedSize, int requestedSize) {
        return JVM.flush(this, usedSize, requestedSize);
    }

    public boolean beginEvent(PlatformEventType eventType) {
        if (started) {
            // recursive write attempt
            return false;
        }
        started = true;
        this.eventType = eventType;
        reserveEventSizeField();
        putLong(eventType.getId());
        return true;
    }

    public boolean endEvent() {
        if (!valid) {
            reset();
            return true;
        }
        final int eventSize = usedSize();
        if (eventSize > maxEventSize) {
            reset();
            return true;
        }
        Bits.putInt(startPosition, makePaddedInt(eventSize));
        if (isNotified()) {
            resetNotified();
            reset();
            // returning false will trigger restart of the event write attempt
            return false;
        }
        startPosition = currentPosition;
        unsafe.putAddress(startPositionAddress, startPosition);
        // the event is now committed
        if (flushOnEnd) {
            flushOnEnd = flush();
        }
        started = false;
        return true;
    }

    private EventWriter(long startPos, long maxPos, long startPosAddress, long threadID, boolean valid) {
        startPosition = currentPosition = startPos;
        maxPosition = maxPos;
        startPositionAddress = startPosAddress;
        this.threadID = threadID;
        started = false;
        flushOnEnd = false;
        this.valid = valid;
        notified = false;
        // event may not exceed size for a padded integer
        maxEventSize = (1 << 28) -1;
    }

    private static int makePaddedInt(int v) {
        // bit  0-6 + pad => bit 24 - 31
        long b1 = (((v >>> 0) & 0x7F) | 0x80) << 24;

        // bit  7-13 + pad => bit 16 - 23
        long b2 = (((v >>> 7) & 0x7F) | 0x80) << 16;

        // bit 14-20 + pad => bit  8 - 15
        long b3 = (((v >>> 14) & 0x7F) | 0x80) << 8;

        // bit 21-28       => bit  0 -  7
        long b4 = (((v >>> 21) & 0x7F)) << 0;

        return (int) (b1 + b2 + b3 + b4);
    }

    private void putUncheckedLong(long v) {
        if ((v & ~0x7FL) == 0L) {
            putUncheckedByte((byte) v); // 0-6
            return;
        }
        putUncheckedByte((byte) (v | 0x80L)); // 0-6
        v >>>= 7;
        if ((v & ~0x7FL) == 0L) {
            putUncheckedByte((byte) v); // 7-13
            return;
        }
        putUncheckedByte((byte) (v | 0x80L)); // 7-13
        v >>>= 7;
        if ((v & ~0x7FL) == 0L) {
            putUncheckedByte((byte) v); // 14-20
            return;
        }
        putUncheckedByte((byte) (v | 0x80L)); // 14-20
        v >>>= 7;
        if ((v & ~0x7FL) == 0L) {
            putUncheckedByte((byte) v); // 21-27
            return;
        }
        putUncheckedByte((byte) (v | 0x80L)); // 21-27
        v >>>= 7;
        if ((v & ~0x7FL) == 0L) {
            putUncheckedByte((byte) v); // 28-34
            return;
        }
        putUncheckedByte((byte) (v | 0x80L)); // 28-34
        v >>>= 7;
        if ((v & ~0x7FL) == 0L) {
            putUncheckedByte((byte) v); // 35-41
            return;
        }
        putUncheckedByte((byte) (v | 0x80L)); // 35-41
        v >>>= 7;
        if ((v & ~0x7FL) == 0L) {
            putUncheckedByte((byte) v); // 42-48
            return;
        }
        putUncheckedByte((byte) (v | 0x80L)); // 42-48
        v >>>= 7;

        if ((v & ~0x7FL) == 0L) {
            putUncheckedByte((byte) v); // 49-55
            return;
        }
        putUncheckedByte((byte) (v | 0x80L)); // 49-55
        putUncheckedByte((byte) (v >>> 7)); // 56-63, last byte as is.
    }

    private void putUncheckedByte(byte i) {
        unsafe.putByte(currentPosition, i);
        ++currentPosition;
    }
}
