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

import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;

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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import android.content.Context;
import android.platform.test.annotations.Presubmit;
import android.util.proto.ProtoOutputStream;

import androidx.test.filters.SmallTest;

import com.android.internal.util.Preconditions;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.File;


/**
 * Test class for {@link TraceBuffer}.
 *
 * Build/Install/Run:
 *  atest WmTests:TraceBufferTest
 */
@SmallTest
@Presubmit
public class TraceBufferTest {
    private File mFile;
    private TraceBuffer mBuffer;

    @Before
    public void setUp() throws Exception {
        final Context testContext = getInstrumentation().getContext();
        mFile = testContext.getFileStreamPath("tracing_test.dat");
        mFile.delete();

        mBuffer = new TraceBuffer(10);
    }

    @After
    public void tearDown() throws Exception {
        mFile.delete();
    }

    @Test
    public void test_addItem() {
        ProtoOutputStream toWrite = getDummy(1);
        final int objectSize = toWrite.getRawSize();
        mBuffer.setCapacity(objectSize);
        mBuffer.resetBuffer();

        Preconditions.checkArgument(mBuffer.size() == 0);

        mBuffer.add(toWrite);

        assertEquals("Item was not added to the buffer", 1, mBuffer.size());
        assertEquals("Total buffer getSize differs from inserted object",
                mBuffer.getBufferSize(), objectSize);
        assertEquals("Available buffer space does not match used one", 0,
                mBuffer.getAvailableSpace());
    }

    @Test
    public void test_addItemMustOverwriteOne() {
        ProtoOutputStream toWrite1 = getDummy(1);
        ProtoOutputStream toWrite2 = getDummy(2);
        ProtoOutputStream toWrite3 = getDummy(3);
        final int objectSize = toWrite1.getRawSize();
        final int bufferCapacity = objectSize * 2 + 1;
        mBuffer.setCapacity(bufferCapacity);
        mBuffer.resetBuffer();

        mBuffer.add(toWrite1);
        byte[] toWrite1Bytes = toWrite1.getBytes();
        assertTrue("First element should be in the list",
                mBuffer.contains(toWrite1Bytes));

        mBuffer.add(toWrite2);
        byte[] toWrite2Bytes = toWrite2.getBytes();
        assertTrue("First element should be in the list",
                mBuffer.contains(toWrite1Bytes));
        assertTrue("Second element should be in the list",
                mBuffer.contains(toWrite2Bytes));

        mBuffer.add(toWrite3);
        byte[] toWrite3Bytes = toWrite3.getBytes();
        assertTrue("First element should not be in the list",
                !mBuffer.contains(toWrite1Bytes));
        assertTrue("Second element should be in the list",
                mBuffer.contains(toWrite2Bytes));
        assertTrue("Third element should be in the list",
                mBuffer.contains(toWrite3Bytes));
        assertEquals("Buffer should have 2 elements", 2, mBuffer.size());
        assertEquals(String.format("Buffer is full, used space should be %d", bufferCapacity),
                mBuffer.getBufferSize(), bufferCapacity - 1);
        assertEquals(" Buffer is full, available space should be 0", 1,
                mBuffer.getAvailableSpace());
    }

    @Test
    public void test_addItemMustOverwriteMultiple() {
        ProtoOutputStream toWriteSmall1 = getDummy(1);
        ProtoOutputStream toWriteSmall2 = getDummy(2);
        final int objectSize = toWriteSmall1.getRawSize();
        final int bufferCapacity = objectSize * 2;
        mBuffer.setCapacity(bufferCapacity);
        mBuffer.resetBuffer();

        ProtoOutputStream toWriteBig = new ProtoOutputStream();
        toWriteBig.write(MAGIC_NUMBER, 1);
        toWriteBig.write(MAGIC_NUMBER, 2);

        mBuffer.add(toWriteSmall1);
        byte[] toWriteSmall1Bytes = toWriteSmall1.getBytes();
        assertTrue("First element should be in the list",
                mBuffer.contains(toWriteSmall1Bytes));

        mBuffer.add(toWriteSmall2);
        byte[] toWriteSmall2Bytes = toWriteSmall2.getBytes();
        assertTrue("First element should be in the list",
                mBuffer.contains(toWriteSmall1Bytes));
        assertTrue("Second element should be in the list",
                mBuffer.contains(toWriteSmall2Bytes));

        mBuffer.add(toWriteBig);
        byte[] toWriteBigBytes = toWriteBig.getBytes();
        assertTrue("Third element should overwrite all others",
                !mBuffer.contains(toWriteSmall1Bytes));
        assertTrue("Third element should overwrite all others",
                !mBuffer.contains(toWriteSmall2Bytes));
        assertTrue("Third element should overwrite all others",
                mBuffer.contains(toWriteBigBytes));

        assertEquals(" Buffer should have only 1 big element", 1, mBuffer.size());
        assertEquals(String.format(" Buffer is full, used space should be %d", bufferCapacity),
                mBuffer.getBufferSize(), bufferCapacity);
        assertEquals(" Buffer is full, available space should be 0", 0,
                mBuffer.getAvailableSpace());
    }

    @Test
    public void test_startResetsBuffer() {
        ProtoOutputStream toWrite = getDummy(1);
        mBuffer.resetBuffer();
        Preconditions.checkArgument(mBuffer.size() == 0);

        mBuffer.add(toWrite);
        assertEquals("Item was not added to the buffer", 1, mBuffer.size());
        mBuffer.resetBuffer();
        assertEquals("Buffer should be empty after reset", 0, mBuffer.size());
        assertEquals("Buffer size should be 0 after reset", 0, mBuffer.getBufferSize());
    }

    private ProtoOutputStream getDummy(int value) {
        ProtoOutputStream toWrite = new ProtoOutputStream();
        toWrite.write(MAGIC_NUMBER, value);
        toWrite.flush();

        return toWrite;
    }

}
