/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed 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.android.server.wm;

import static com.android.server.wm.WindowManagerTraceFileProto.MAGIC_NUMBER;
import static com.android.server.wm.WindowManagerTraceFileProto.MAGIC_NUMBER_H;
import static com.android.server.wm.WindowManagerTraceFileProto.MAGIC_NUMBER_L;

import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.VisibleForTesting;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Queue;

/**
 * Buffer used for window tracing.
 */
class WindowTraceBuffer {
    private static final long MAGIC_NUMBER_VALUE = ((long) MAGIC_NUMBER_H << 32) | MAGIC_NUMBER_L;

    private final Object mBufferLock = new Object();

    private final Queue<ProtoOutputStream> mBuffer = new ArrayDeque<>();
    private int mBufferUsedSize;
    private int mBufferCapacity;

    WindowTraceBuffer(int bufferCapacity) {
        mBufferCapacity = bufferCapacity;
        resetBuffer();
    }

    int getAvailableSpace() {
        return mBufferCapacity - mBufferUsedSize;
    }

    int size() {
        return mBuffer.size();
    }

    void setCapacity(int capacity) {
        mBufferCapacity = capacity;
    }

    /**
     * Inserts the specified element into this buffer.
     *
     * @param proto the element to add
     * @throws IllegalStateException if the element cannot be added because it is larger
     *                               than the buffer size.
     */
    void add(ProtoOutputStream proto) {
        int protoLength = proto.getRawSize();
        if (protoLength > mBufferCapacity) {
            throw new IllegalStateException("Trace object too large for the buffer. Buffer size:"
                    + mBufferCapacity + " Object size: " + protoLength);
        }
        synchronized (mBufferLock) {
            discardOldest(protoLength);
            mBuffer.add(proto);
            mBufferUsedSize += protoLength;
            mBufferLock.notify();
        }
    }

    boolean contains(byte[] other) {
        return mBuffer.stream()
                .anyMatch(p -> Arrays.equals(p.getBytes(), other));
    }

    /**
     * Writes the trace buffer to disk.
     */
    void writeTraceToFile(File traceFile) throws IOException {
        synchronized (mBufferLock) {
            traceFile.delete();
            try (OutputStream os = new FileOutputStream(traceFile)) {
                traceFile.setReadable(true /* readable */, false /* ownerOnly */);
                ProtoOutputStream proto = new ProtoOutputStream();
                proto.write(MAGIC_NUMBER, MAGIC_NUMBER_VALUE);
                os.write(proto.getBytes());
                for (ProtoOutputStream protoOutputStream : mBuffer) {
                    proto = protoOutputStream;
                    byte[] protoBytes = proto.getBytes();
                    os.write(protoBytes);
                }
                os.flush();
            }
        }
    }

    /**
     * Checks if the element can be added to the buffer. The element is already certain to be
     * smaller than the overall buffer size.
     *
     * @param protoLength byte array representation of the Proto object to add
     */
    private void discardOldest(int protoLength) {
        long availableSpace = getAvailableSpace();

        while (availableSpace < protoLength) {

            ProtoOutputStream item = mBuffer.poll();
            if (item == null) {
                throw new IllegalStateException("No element to discard from buffer");
            }
            mBufferUsedSize -= item.getRawSize();
            availableSpace = getAvailableSpace();
        }
    }

    /**
     * Removes all elements form the buffer
     */
    void resetBuffer() {
        synchronized (mBufferLock) {
            mBuffer.clear();
            mBufferUsedSize = 0;
        }
    }

    @VisibleForTesting
    int getBufferSize() {
        return mBufferUsedSize;
    }

    String getStatus() {
        synchronized (mBufferLock) {
            return "Buffer size: "
                    + mBufferCapacity
                    + " bytes"
                    + "\n"
                    + "Buffer usage: "
                    + mBufferUsedSize
                    + " bytes"
                    + "\n"
                    + "Elements in the buffer: "
                    + mBuffer.size();
        }
    }
}
