/*
 * Copyright (C) 2013 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.loganalysis.parser;

import com.android.loganalysis.item.KernelLogItem;
import com.android.loganalysis.item.MiscKernelLogItem;
import com.android.loganalysis.item.SELinuxItem;
import com.android.loganalysis.util.LogPatternUtil;

import junit.framework.TestCase;

import java.util.Arrays;
import java.util.List;

/**
 * Unit tests for {@link KernelLogParser}.
 */
public class KernelLogParserTest extends TestCase {
    /**
     * Test that log lines formatted by last kmsg are able to be parsed.
     */
    public void testParseLastKmsg() {
        List<String> lines = Arrays.asList(
                "[    0.000000] Start",
                "[    1.000000] Kernel panic",
                "[    2.000000] End");

        KernelLogItem kernelLog = new KernelLogParser().parse(lines);
        assertNotNull(kernelLog);
        assertEquals(0.0, kernelLog.getStartTime(), 0.0000005);
        assertEquals(2.0, kernelLog.getStopTime(), 0.0000005);
        assertEquals(1, kernelLog.getEvents().size());
        assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).size());

        MiscKernelLogItem item = kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).get(0);
        assertEquals(1.0, item.getEventTime(), 0.0000005);
        assertEquals("[    0.000000] Start", item.getPreamble());
        assertEquals("Kernel panic", item.getStack());
    }

    /**
     * Test that log lines formatted by dmsg are able to be parsed.
     */
    public void testParseDmesg() {
        List<String> lines = Arrays.asList(
                "<1>[    0.000000] Start",
                "<1>[    1.000000] Kernel panic",
                "<1>[    2.000000] End");

        KernelLogItem kernelLog = new KernelLogParser().parse(lines);
        assertNotNull(kernelLog);
        assertEquals(0.0, kernelLog.getStartTime(), 0.0000005);
        assertEquals(2.0, kernelLog.getStopTime(), 0.0000005);
        assertEquals(1, kernelLog.getEvents().size());
        assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).size());

        MiscKernelLogItem item = kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).get(0);
        assertEquals(1.0, item.getEventTime(), 0.0000005);
        assertEquals("<1>[    0.000000] Start", item.getPreamble());
        assertEquals("Kernel panic", item.getStack());
    }

    /**
     * Test that last boot reasons are parsed.
     */
    public void testParseLastMessage() {
        List<String> lines = Arrays.asList(
                "[    0.000000] Start",
                "[    2.000000] End",
                "Last boot reason: hw_reset");

        KernelLogItem kernelLog = new KernelLogParser().parse(lines);
        assertNotNull(kernelLog);
        assertEquals(0.0, kernelLog.getStartTime(), 0.0000005);
        assertEquals(2.0, kernelLog.getStopTime(), 0.0000005);
        assertEquals(1, kernelLog.getEvents().size());
        assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).size());

        MiscKernelLogItem item = kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).get(0);
        assertEquals(2.0, item.getEventTime(), 0.0000005);
        assertEquals("[    0.000000] Start\n[    2.000000] End", item.getPreamble());
        assertEquals("Last boot reason: hw_reset", item.getStack());
    }

    /**
     * Test that reset reasons don't crash if times are set.
     */
    public void testNoPreviousLogs() {
        List<String> lines = Arrays.asList(
                "Last boot reason: hw_reset");

        KernelLogItem kernelLog = new KernelLogParser().parse(lines);
        assertNotNull(kernelLog);
        assertNull(kernelLog.getStartTime());
        assertNull(kernelLog.getStopTime());
        assertEquals(1, kernelLog.getEvents().size());
        assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).size());

        MiscKernelLogItem item = kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).get(0);
        assertNull(item.getEventTime());
        assertEquals("", item.getPreamble());
        assertEquals("Last boot reason: hw_reset", item.getStack());
    }

    /**
     * Test that an empty input returns {@code null}.
     */
    public void testEmptyInput() {
        KernelLogItem item = new KernelLogParser().parse(Arrays.asList(""));
        assertNull(item);
    }

    /**
     * Test that kernel patterns are matched.
     */
    public void testPatterns() {
        List<String> kernelResetPatterns = Arrays.asList(
                "smem: DIAG",
                "smsm: AMSS FATAL ERROR",
                "kernel BUG at ",
                "PVR_K:(Fatal): Debug assertion failed! []",
                "Kernel panic",
                "BP panicked",
                "WROTE DSP RAMDUMP",
                "tegra_wdt: last reset due to watchdog timeout",
                "tegra_wdt tegra_wdt.0: last reset is due to watchdog timeout.",
                "Last reset was MPU Watchdog Timer reset",
                "[MODEM_IF] CRASH",
                "Last boot reason: kernel_panic",
                "Last boot reason: rpm_err",
                "Last boot reason: hw_reset",
                "Last boot reason: wdog_",
                "Last boot reason: tz_err",
                "Last boot reason: adsp_err",
                "Last boot reason: modem_err",
                "Last boot reason: mba_err",
                "Last boot reason: watchdog",
                "Last boot reason: watchdogr",
                "Last boot reason: Watchdog",
                "Last boot reason: Panic",
                "Last reset was system watchdog timer reset");

        LogPatternUtil patternUtil = new KernelLogParser().getLogPatternUtil();

        for (String pattern : kernelResetPatterns) {
            assertEquals(String.format("Message \"%s\" was not matched.", pattern),
                    KernelLogParser.KERNEL_RESET, patternUtil.checkMessage(pattern));
        }

        assertEquals(KernelLogParser.KERNEL_ERROR, patternUtil.checkMessage("Internal error:"));
        assertEquals(KernelLogParser.SELINUX_DENIAL, patternUtil.checkMessage(
                    "avc: denied scontext=0:0:domain:0 "));
    }

    /**
     * Test that an SELinux Denial can be parsed out of a list of log lines.
     */
    public void testSelinuxDenialParse() {
        final String SELINUX_DENIAL_STACK = "type=1400 audit(1384544483.730:10): avc:  denied  " +
                "{ getattr } for  pid=797 comm=\"Binder_5\" path=\"/dev/pts/1\" + " +
                "dev=devpts ino=4 scontext=u:r:system_server:s0 " +
                "tcontext=u:object_r:devpts:s0 tclass=chr_file";
        List<String> lines = Arrays.asList(
                "<4>[    0.000000] Memory policy: ECC disabled, Data cache writealloc",
                "<7>[    7.896355] SELinux: initialized (dev cgroup, type cgroup)" +
                        ", uses genfs_contexts",
                "<5>[   43.399164] " + SELINUX_DENIAL_STACK);
        KernelLogItem kernelLog = new KernelLogParser().parse(lines);

        assertNotNull(kernelLog);
        assertEquals(0.0, kernelLog.getStartTime(), 0.0000005);
        assertEquals(43.399164, kernelLog.getStopTime(), 0.0000005);
        assertEquals(1, kernelLog.getEvents().size());
        assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.SELINUX_DENIAL).size());
        assertEquals(1, kernelLog.getSELinuxEvents().size());

        MiscKernelLogItem item = kernelLog.getMiscEvents(KernelLogParser.SELINUX_DENIAL).get(0);
        assertEquals(43.399164, item.getEventTime(), 0.0000005);
        assertEquals(KernelLogParser.SELINUX_DENIAL, item.getCategory());
        assertEquals(SELINUX_DENIAL_STACK, item.getStack());

        SELinuxItem selinuxItem = kernelLog.getSELinuxEvents().get(0);
        assertEquals("system_server", selinuxItem.getSContext());
        assertEquals(43.399164, selinuxItem.getEventTime(), 0.0000005);
        assertEquals(KernelLogParser.SELINUX_DENIAL, selinuxItem.getCategory());
        assertEquals(SELINUX_DENIAL_STACK, selinuxItem.getStack());
    }

    public void testMantaReset() {
        final List<String> lines = Arrays.asList("[ 3281.347296] ---fimc_is_ischain_close(0)",
                "[ 3281.432055] fimc_is_scalerc_video_close",
                "[ 3281.432270] fimc_is_scalerp_video_close",
                "[ 3287.688303] wm8994-codec wm8994-codec: FIFO error",
                "",
                "No errors detected",
                "Last reset was system watchdog timer reset (RST_STAT=0x100000)");

        KernelLogItem kernelLog = new KernelLogParser().parse(lines);
        assertEquals(1, kernelLog.getEvents().size());
        assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).size());
    }

    /**
     * Test that only the first kernel reset is taken but other signatures can have multiple
     */
    public void testMultipleKernelResets() {
        final String SELINUX_DENIAL_STACK = "type=1400 audit(1384544483.730:10): avc:  denied  " +
                "{ getattr } for  pid=797 comm=\"Binder_5\" path=\"/dev/pts/1\" + " +
                "dev=devpts ino=4 scontext=u:r:system_server:s0 " +
                "tcontext=u:object_r:devpts:s0 tclass=chr_file";
        final List<String> lines = Arrays.asList(
                "[ 0.000000] Kernel panic",
                "[ 0.000000] Internal error:",
                "[ 0.000000] " + SELINUX_DENIAL_STACK,
                "[ 1.000000] Kernel panic",
                "[ 1.000000] Internal error:",
                "[ 1.000000] " + SELINUX_DENIAL_STACK,
                "[ 2.000000] Kernel panic",
                "[ 2.000000] Internal error:",
                "[ 2.000000] " + SELINUX_DENIAL_STACK);

        KernelLogItem kernelLog = new KernelLogParser().parse(lines);
        assertEquals(7, kernelLog.getEvents().size());
        assertEquals(1, kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).size());
        assertEquals(0.0,
                kernelLog.getMiscEvents(KernelLogParser.KERNEL_RESET).get(0).getEventTime());
    }
}
