package com.android.server.devicepolicy;

import static android.app.admin.SecurityLog.TAG_ADB_SHELL_CMD;

import android.app.admin.SecurityLog.SecurityEvent;
import android.os.Parcel;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.EventLog;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@SmallTest
public class SecurityEventTest extends DpmTestBase {
    private static long ID = 549;
    private static String DATA = "adb shell some_command";

    public void testSecurityEventId() {
        SecurityEvent event = buildSecurityEvents(1 /* generate a single event */, ID).get(0);
        assertEquals(ID, event.getId());
        event.setId(20);
        assertEquals(20, event.getId());
    }

    public void testSecurityEventParceling() {
        // GIVEN an event.
        SecurityEvent event = buildSecurityEvents(1 /* generate a single event */, ID).get(0);
        // WHEN parceling the event.
        Parcel p = Parcel.obtain();
        p.writeParcelable(event, 0);
        p.setDataPosition(0);
        SecurityEvent unparceledEvent = p.readParcelable(SecurityEventTest.class.getClassLoader());
        p.recycle();
        // THEN the event state is preserved.
        assertEquals(event.getTag(), unparceledEvent.getTag());
        assertEquals(event.getData(), unparceledEvent.getData());
        assertEquals(event.getTimeNanos(), unparceledEvent.getTimeNanos());
        assertEquals(event.getId(), unparceledEvent.getId());
    }

    private List<SecurityEvent> buildSecurityEvents(int numEvents, long id) {
        // Write an event to the EventLog.
        for (int i = 0; i < numEvents; i++) {
            EventLog.writeEvent(TAG_ADB_SHELL_CMD, DATA + "_" + i);
        }
        List<EventLog.Event> events = new ArrayList<>();
        try {
            EventLog.readEvents(new int[]{TAG_ADB_SHELL_CMD}, events);
        } catch (IOException e) {
            fail("Reading a test event from storage failed: " + e);
        }
        assertTrue("Unexpected number of events read from the log.", events.size() >= numEvents);
        // Read events generated by test, from the end of the log.
        List<SecurityEvent> securityEvents = new ArrayList<>();
        for (int i = events.size() - numEvents; i < events.size(); i++) {
          securityEvents.add(new SecurityEvent(id++, events.get(i).getBytes()));
        }
        return securityEvents;
    }
}
