/*******************************************************************************
 * Copyright (c) 2014, 2015 Ericsson
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License 2.0 which
 * accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *   Alexandre Montplaisir - Initial API and implementation
 ******************************************************************************/

package org.eclipse.tracecompass.analysis.os.linux.core.trace;

import java.util.Collection;
import java.util.Collections;

import org.eclipse.jdt.annotation.Nullable;

/**
 * Interface to define "concepts" present in the Linux kernel (represented by
 * its tracepoints), that can then be exposed by different tracers under
 * different names.
 *
 * @author Alexandre Montplaisir
 * @author Matthew Khouzam - Javadoc
 */
public interface IKernelAnalysisEventLayout {

    // ------------------------------------------------------------------------
    // Common definitions
    // ------------------------------------------------------------------------

    /**
     * Whenever a process appears for the first time in a trace, we assume it
     * starts inside this system call. (The syscall prefix is defined by the
     * implementer of this interface.)
     *
     * TODO Change to a default method with Java 8?
     */
    String INITIAL_SYSCALL_NAME = "clone"; //$NON-NLS-1$

    // ------------------------------------------------------------------------
    // Event names
    // ------------------------------------------------------------------------

    /**
     * The system has just entered an interrupt handler or interrupt service
     * routine. On some systems, this is known as the first level interrupt
     * handler.
     *
     * @return the event name
     */
    String eventIrqHandlerEntry();

    /**
     * The system will soon return from an interrupt handler or interrupt
     * service routine.
     *
     * @return the event name
     */
    String eventIrqHandlerExit();

    /**
     * Whenever a system call is about to return to userspace, or a hardware
     * interrupt handler exits, any 'software interrupts' which are marked
     * pending (usually by hardware interrupts) are run. Much of the real
     * interrupt handling work is done here. The soft IRQ is also known as a
     * deferred IRQ in windows. An event identifying as this needs to occur as
     * the system is beginning to process the interrupt.
     *
     * @return the event name
     */
    String eventSoftIrqEntry();

    /**
     * Whenever a system call is about to return to userspace, or a hardware
     * interrupt handler exits, any 'software interrupts' which are marked
     * pending (usually by hardware interrupts) are run Much of the real
     * interrupt handling work is done here. The soft IRQ is also known as a
     * deferred IRQ in windows. An event identifying as this needs to occur as
     * the system is returning from the interrupt.
     *
     * @return the event name
     */
    String eventSoftIrqExit();

    /**
     * Whenever a system call is about to return to userspace, or a hardware
     * interrupt handler exits, any 'software interrupts' which are marked
     * pending (usually by hardware interrupts) are run Much of the real
     * interrupt handling work is done here. The soft IRQ is also known as a
     * deferred IRQ in windows. An event identifying as this needs to occur as
     * the system is signaling the need to enter the interrupt.
     *
     * @return the event name
     */
    String eventSoftIrqRaise();

    /**
     * The scheduler will call a scheduler switch event when it is removing a
     * task from a cpu and placing another one in its place. Which task and when
     * depend on the scheduling strategy and the task priorities. This is a
     * context switch.
     *
     * @return the event name
     */
    String eventSchedSwitch();

    /**
     * sched_PI_setprio is a tracepoint called often when the schedulder
     * priorities for a given task changes.
     *
     * @return the event name
     * @since 1.0
     */
    String eventSchedPiSetprio();

    /**
     * Scheduler is waking up a task. this happens before it is executed, and
     * the data is loaded in memory if needed.
     *
     * @return the event names, as there are often several different ways to
     *         wake up
     */
    Collection<String> eventsSchedWakeup();

    /**
     * Scheduler just forked a process, that means it has duplicated the program
     * and assigned it a different process ID. This event is often followed by
     * an {@link #eventSchedProcessExec()}. In windows, this is part of the
     * "spawn" process.
     *
     * @return the event name
     */
    String eventSchedProcessFork();

    /**
     * The process has finished running and the scheduler takes its TID back.
     *
     * @return the event name
     */
    String eventSchedProcessExit();

    /**
     * The process free tracepoint is called when a process has finished running
     * and the scheduler retrieves it's process ID.
     *
     * @return the event name
     */
    String eventSchedProcessFree();

    /**
     * Optional event used by some tracers to deliver an initial state.
     *
     * @return the event name
     */
    @Nullable String eventStatedumpProcessState();

    /**
     * System call entry prefix, something like "sys_open" or just "sys".
     *
     * @return the event name
     */
    String eventSyscallEntryPrefix();

    /**
     * System call compatibility layer entry prefix, something like
     * "compat_sys".
     *
     * @return the event name
     */
    String eventCompatSyscallEntryPrefix();

    /**
     * System call exit prefix, something like "sys_exit".
     *
     * @return the event name
     */
    String eventSyscallExitPrefix();

    /**
     * System call compatibility layer exit prefix, something like
     * "compat_syscall_exit".
     *
     * @return the event name
     * @since 2.0
     */
    String eventCompatSyscallExitPrefix();

    /**
     * The scheduler replaced the current process image with a new one. The
     * process should also be renamed at this point. In windows, this is part of
     * the spawn process as well as fork.
     *
     * @return the event name
     *
     * @since 2.0
     */
    String eventSchedProcessExec();

    /**
     * The scheduler calls wakeup on a sleeping process. The process will
     * probably soon be scheduled in.
     *
     * @return the event name
     *
     * @since 2.0
     */
    String eventSchedProcessWakeup();

    /**
     * The scheduler calls wakeup on a sleeping process. The process will
     * probably soon be scheduled in. The new wakeup knows who triggered the
     * wakeup.
     *
     * @return the event name
     *
     * @since 2.0
     */
    String eventSchedProcessWakeupNew();

    /**
     * Event called when waking a task; this event is guaranteed to be called
     * from the waking context.
     *
     * @return The name of the event
     * @since 2.2
     */
    default String eventSchedProcessWaking() {
        return "sched_waking"; //$NON-NLS-1$
    }

    /**
     * Migration event, moving a non-running thread from one CPU's run queue to
     * another.
     *
     * @return The event name
     * @since 2.5
     */
    default String eventSchedMigrateTask() {
        return "sched_migrate_task"; //$NON-NLS-1$
    }

    /**
     * Starting the high resolution timer
     * <p>
     * In Linux, High resolution timers are used in the following:
     * <ul>
     * <li>nanosleep</li>
     * <li>itimers</li>
     * <li>posix timers</li>
     * </ul>
     *
     * @return the event name
     *
     * @since 2.0
     */
    String eventHRTimerStart();

    /**
     * Canceling the high resolution timer
     * <p>
     * In Linux, High resolution timers are used in the following:
     * <ul>
     * <li>nanosleep</li>
     * <li>itimers</li>
     * <li>posix timers</li>
     * </ul>
     *
     * @return the event name
     *
     * @since 2.0
     */
    String eventHRTimerCancel();

    /**
     * Entering the high resolution timer expired handler.
     * <p>
     * In Linux, High resolution timers are used in the following:
     * <ul>
     * <li>nanosleep</li>
     * <li>itimers</li>
     * <li>posix timers</li>
     * </ul>
     *
     * @return the event name
     *
     * @since 2.0
     */
    String eventHRTimerExpireEntry();

    /**
     * Exiting the high resolution timer expired handler.
     * <p>
     * In Linux, High resolution timers are used in the following:
     * <ul>
     * <li>nanosleep</li>
     * <li>itimers</li>
     * <li>posix timers</li>
     * </ul>
     *
     * @return the event name
     *
     * @since 2.0
     */
    String eventHRTimerExpireExit();

    /**
     * The kernel just allocated a page of memory.
     * <p>
     * In Linux, this typically means a user space application just got a page
     * of ram.
     *
     * @return the event name
     * @since 2.0
     */
    String eventKmemPageAlloc();

    /**
     * The kernel just deallocated a page of memory.
     * <p>
     * In Linux, this typically means a page of ram was just freed
     *
     * @return the event name
     * @since 2.0
     */
    String eventKmemPageFree();

    /**
     * <em>Interprocessor interrupts</em> (IPIs) are special types of interrupts by which
     * one processor will interrupt another in a multi-core and multi-cpu system. They are
     * typically used for
     * <ol>
     * <li>cache flushes</li>
     * <li>shutdowns</li>
     * <ol>
     * They are not logged with standard events, but rather events looking like
     * "x86_irq_vectors_thermal_apic_exit".
     * <p>
     * This event describes the entries into IPIs.
     *
     * @return the IPI list
     * @since 2.1
     */
    default Collection<String> getIPIIrqVectorsEntries() {
        return Collections.emptyList();
    }

    /**
     * <em>Interprocessor interrupts</em> (IPIs) are special types of interrupts by which
     * one processor will interrupt another in a multi-core and multi-cpu system. They are
     * typically used for
     * <ol>
     * <li>cache flushes</li>
     * <li>shutdowns</li>
     * <ol>
     * They are not logged with standard events, but rather events looking like
     * "x86_irq_vectors_thermal_apic_exit".
     * <p>
     * This event describes the exits into IPIs.
     *
     * @return the IPI list
     * @since 2.1
     */
    default Collection<String> getIPIIrqVectorsExits() {
        return Collections.emptyList();
    }

    // ------------------------------------------------------------------------
    // Event field names
    // ------------------------------------------------------------------------

    /**
     * The field with the IRQ number. This is used in irq_handlers (entry and
     * exit). For soft IRQs see {@link #fieldVec}.
     *
     * @return the name of the field with the IRQ number
     */
    String fieldIrq();

    /**
     * The field with the vector. This is the soft IRQ vector field used in soft
     * IRQ raise, entry and exit. For hardware IRQs see {@link #fieldIrq}.
     *
     * @return the name of the field with the soft IRQ vector name
     */
    String fieldVec();

    /**
     * The field with the thread ID. This is often used in scheduler calls to
     * know which thread is being affected. (normally not in switch, but in
     * priority and wakeup calls).
     *
     * @return the name of the field with the thread ID
     */
    String fieldTid();

    /**
     * The field with the previous thread id. This is used in switching
     * operations of a scheduler, when a thread is scheduled out for another,
     * this field shows the thread id being scheduled out.
     *
     * @return The name of the field with the ID of the previous thread
     */
    String fieldPrevTid();

    /**
     * The field with the state of the previous thread. This is used in
     * switching operations of a scheduler, when a thread is scheduled out for
     * another, this field shows the state of the thread being scheduled out.
     *
     * @return the name of the field of the previous thread's state
     */
    String fieldPrevState();

    /**
     * The field with the next command to be run. This is used in switching
     * operations of a scheduler, when a thread is scheduled out for another,
     * this field shows the command being scheduled in. A command's value is
     * often a String like "ls" or "hl3.exe".
     *
     * @return the name of the field with the next command to be run
     */
    String fieldNextComm();

    /**
     * The field with the next thread ID. This is used in switching operations
     * of a scheduler, when a thread is scheduled out for another, this field
     * shows the thread being scheduled in.
     *
     * @return the name of the field with the next thread ID
     */
    String fieldNextTid();

    /**
     * The field with the child command. This field is used in clone and spawn
     * activities, to know which executable the clone is running.
     *
     * @return the name of the field with the child command
     */
    String fieldChildComm();

    /**
     * The field with the parent thread ID. This field is used in clone and
     * spawn activities, to know which thread triggered the clone.
     *
     * @return the name of the field with the parent thread ID
     */
    String fieldParentTid();

    /**
     * The field with the child thread ID. This field is used in clone and spawn
     * activities, to know which thread is the clone.
     *
     * @return the name of the field with the child thread ID
     */
    String fieldChildTid();

    /**
     * The field with the child process ID. This field is used in clone and spawn
     * activities, to know what is the process of the thread being cloned.
     *
     * @return the name of the field with the child process ID
     * @since 2.5
     */
    default String fieldChildPid() {
        return "child_pid"; //$NON-NLS-1$
    }

    /**
     * The field with the command. This is used in scheduling tracepoints that
     * are not switches, and show the current process name. It is often a string
     * like "zsh" or "cmd.exe".
     *
     * @return the name of the command field
     * @since 2.0
     */
    String fieldComm();

    /**
     * The field with the name. The name field is used in several disjoint
     * events.
     * <p>
     * Examples include:
     * <ul>
     * <li>writeback_* - the name of the io device, often "(unknown)"</li>
     * <li>module_* - the name of the module such as "binfmt_misc"</li>
     * <li>irq_handler_entry - the field describes the name of the handler such
     * as "i915"</li>
     * <ul>
     *
     * @return the name of the field with a name
     * @since 2.0
     */
    String fieldName();

    /**
     * The field with the status. Often functions like a return value before we
     * hit an exit.
     * <p>
     * Examples include:
     * <ul>
     * <li>ext4* - status</li>
     * <li>asoc_snd_soc_cache_sync</li>
     * <li>rpc_*</li>
     * <li>state dumps</li>
     * </ul>
     *
     * @return The name of the field with a status
     * @since 2.0
     */
    String fieldStatus();

    /**
     * The field with the last command to be run. This is often a string
     * representing the command of the thread being scheduled out from a
     * scheduler switch operation.
     *
     * @return the name of the field with the last command to be run
     * @since 2.0
     */
    String fieldPrevComm();

    /**
     * The field with the file name field. This is a string used mostly with
     * file operations. These operations are often wrapped in system calls and
     * can be:
     * <ul>
     * <li>open</li>
     * <li>change mode</li>
     * <li>change directory</li>
     * <li>stat</li>
     * </ul>
     * It can also be used in exec commands to see what the command name should
     * be.
     * <p>
     * Please note that file read and write often do not use the file name, they
     * just use the file handle.
     *
     * @return the name of the field with the file name
     * @since 2.0
     */
    String fieldFilename();

    /**
     * The field with the priority. The priority of a given process is used by
     * most scheduler events. The major exception is the switching operation as
     * it has two processes so it has a previous and next priority.
     *
     * @return the name of the field with the thread or process' priority
     * @since 1.0
     */
    String fieldPrio();

    /**
     * The field with the new priority. This is used in the scheduler's
     * pi_setprio event event to show the new priority of the thread or process.
     *
     * @return the name of the field with the thread or process' new priority
     * @since 1.0
     */
    String fieldNewPrio();

    /**
     * The field with the prev priority. This is used in the scheduler's switch
     * event to show the priority of the thread being scheduled out.
     *
     * @return the name of the field with the priority of the previous thread
     * @since 2.0
     */
    String fieldPrevPrio();

    /**
     * The field with the next priority. This is used in the scheduler's switch
     * event to show the priority of the next thread or process.
     *
     * @return the name of the field with the thread or process' next priority
     * @since 1.0
     */
    String fieldNextPrio();

    /**
     * The field with the hrtimer. The hrtimer holds the timer instance.
     *
     * @return the name of the hrTimer field
     * @since 2.0
     */
    String fieldHRtimer();

    /**
     * The field with the expires value. The expires field holds the expiry
     * time. of the hrtimer.
     *
     * @return the name of the expires field
     * @since 2.0
     */
    String fieldHRtimerExpires();

    /**
     * Gets the field name with the softexpires value. The softexpire value is
     * the absolute earliest expiry time of the hrtimer.
     *
     * @return the name of the softexpires field
     * @since 2.0
     */
    String fieldHRtimerSoftexpires();

    /**
     * The field of the function address value. The function field holds timer
     * expiry callback function.
     *
     * @return the name of the function field
     * @since 2.0
     */
    String fieldHRtimerFunction();

    /**
     * The field of the now value. The now field holds the current time.
     *
     * @return the name of the now field (hrtimer)
     * @since 2.0
     */
    String fieldHRtimerNow();

    /**
     * The field containing the return value of a system call exit.
     *
     * @return The name of return field
     * @since 2.0
     */
    default String fieldSyscallRet() {
        return "ret"; //$NON-NLS-1$
    }

    /**
     * Field indicating the upcoming CPU of sched_wakeup and sched_waking
     * events.
     *
     * @return The field name
     * @since 2.5
     */
    default String fieldTargetCpu() {
        return "target_cpu"; //$NON-NLS-1$
    }

    /**
     * Field of scheduler migration events, indicating the destination CPU of a
     * thread being migrated.
     *
     * @return The field name
     * @since 2.5
     */
    default String fieldDestCpu() {
        return "dest_cpu"; //$NON-NLS-1$
    }

    // ------------------------------------------------------------------------
    // I/O events and fields
    // ------------------------------------------------------------------------

    /**
     * A request to a block IO has just been inserted in the waiting queue.
     *
     * @return The name of the event
     * @since 2.0
     */
    default String eventBlockRqInsert() {
        return "block_rq_insert"; //$NON-NLS-1$
    }

    /**
     * A request to a block IO has just been issued and passed from the waiting
     * queue to the driver queue. It is being served.
     *
     * @return The name of the event
     * @since 2.0
     */
    default String eventBlockRqIssue() {
        return "block_rq_issue"; //$NON-NLS-1$
    }

    /**
     * A request to a block IO has just been completed.
     *
     * @return The name of the event
     * @since 2.0
     */
    default String eventBlockRqComplete() {
        return "block_rq_complete"; //$NON-NLS-1$
    }

    /**
     * A BIO operation is being merged at the front of a waiting request
     *
     * @return The name of the event
     * @since 2.0
     */
    default String eventBlockBioFrontmerge() {
        return "block_bio_frontmerge"; //$NON-NLS-1$
    }

    /**
     * A BIO operation is being merged at the back of a waiting request
     *
     * @return The name of the event
     * @since 2.0
     */
    default String eventBlockBioBackmerge() {
        return "block_bio_backmerge"; //$NON-NLS-1$
    }

    /**
     * 2 requests previously inserted in the waiting queue are being merged
     *
     * @return The name of the event
     * @since 2.0
     */
    default String eventBlockRqMerge() {
        return "block_rq_merge"; //$NON-NLS-1$
    }

    /**
     * Optional event used by some tracers to associate the name of the block
     * device to a device ID
     *
     * @return The name of the event
     * @since 2.0
     */
    default @Nullable String eventStatedumpBlockDevice() {
        return null;
    }

    /**
     * The field containing the device ID
     *
     * @return The name of the field
     * @since 2.0
     */
    default String fieldBlockDeviceId() {
        return "dev"; //$NON-NLS-1$
    }

    /**
     * The field with the first sector of a block operation
     *
     * @return The name of the field
     * @since 2.0
     */
    default String fieldBlockSector() {
        return "sector"; //$NON-NLS-1$
    }

    /**
     * The field with the number of sectors involved in a block operation
     *
     * @return The name of the field
     * @since 2.0
     */
    default String fieldBlockNrSector() {
        return "nr_sector"; //$NON-NLS-1$
    }

    /**
     * The field containing the read/write flag of a block operation
     *
     * @return The name of the field
     * @since 2.0
     */
    default String fieldBlockRwbs() {
        return "rwbs"; //$NON-NLS-1$
    }

    /**
     * The field with the first sector of a request in which another block
     * operation is being merged
     *
     * @return The name of the field
     * @since 2.0
     */
    default String fieldBlockRqSector() {
        return "rq_sector"; //$NON-NLS-1$
    }

    /**
     * The field with the sector of the request being merged in another one
     *
     * @return The name of the field
     * @since 2.0
     */
    default String fieldBlockNextRqSector() {
        return "nextrq_sector"; //$NON-NLS-1$
    }

    /**
     * The field containing the name of the disk
     *
     * @return The name of the field
     * @since 2.0
     */
    default String fieldDiskname() {
        return "diskname"; //$NON-NLS-1$
    }

    /**
     * The field with the IRQ number. This is used in IPI handlers (entry and
     * exit).
     *
     * @return the name of the field with the IRQ number
     * @since 2.1
     */
    default String fieldIPIVector() {
        return "vector"; //$NON-NLS-1$
    }


    /**
     * Get the name of the 'order' field from memory page allocation events.
     *
     * The 'order' of a page allocation is it's logarithm to the base 2, and the
     * size of the allocation is 2^order, an integral power-of-2 number of
     * pages. 'Order' ranges from from 0 to MAX_ORDER-1.
     *
     * The smallest - and most frequent - page allocation is 2^0 or 1 page. The
     * maximum allocation possible is 2^(MAX_ORDER-1) pages. MAX_ORDER is
     * assigned a default value of 11 - resulting in a maximum allocation of
     * 2^10 or 1024 pages. However it may be redefined at kernel configuration
     * time with the option CONFIG_FORCE_MAX_ZONEORDER.
     *
     * @return the name of the order field
     * @since 2.2
     */
    default @Nullable String fieldOrder() {
        return null;
    }

    // ------------------------------------------------------------------------
    // Network events and fields
    // ------------------------------------------------------------------------

    /**
     * Get the list of events indicating that a packet is sent on the network
     *
     * @return The name of the packet send event
     * @since 2.1
     */
    default Collection<String> eventsNetworkSend() {
        return Collections.emptySet();
    }

    /**
     * Get the list of events indicating that a packet is received from the
     * network
     *
     * @return The collection of names of the packet receive event
     * @since 2.1
     */
    default Collection<String> eventsNetworkReceive() {
        return Collections.emptySet();
    }

    /**
     * The path of the field corresponding to the sequence number field of a TCP
     * header
     *
     * @return The path of the sequence number field in the TCP header of a
     *         network packet
     * @since 2.1
     */
    default String[] fieldPathTcpSeq() {
        return new String[] { "seq" }; //$NON-NLS-1$
    }

    /**
     * The path of the field corresponding to the acknowledgment number field of
     * a TCP header
     *
     * @return The name of the acknowledgment number field in the TCP header of
     *         a network packet
     * @since 2.1
     */
    default String[] fieldPathTcpAckSeq() {
        return new String[] { "ack_seq" }; //$NON-NLS-1$
    }

    /**
     * The path of the field corresponding to the flags field of a TCP header
     *
     * @return The path of the flags field in the TCP header of a network packet
     * @since 2.1
     */
    default String[] fieldPathTcpFlags() {
        return new String[] { "flags" }; //$NON-NLS-1$
    }

    // ------------------------------------------------------------------------
    // VirtualMachine events : kvm entry/exit events
    // ------------------------------------------------------------------------

    /**
     * KVM kernel event indicating that virtual machine code is being run
     *
     * @return The name of the kvm entry event
     * @since 2.1
     */
    default Collection<String> eventsKVMEntry() {
        return Collections.emptySet();
    }

    /**
     * KVM kernel event indicating that virtual machine code is not run anymore,
     * but rather hypervisor-specific code
     *
     * @return The name of the kvm exit event
     * @since 2.1
     */
    default Collection<String> eventsKVMExit() {
        return Collections.emptySet();
    }

    /**
     * Get the name of the kernel event when the CPU frequency is changed
     *
     * @return The name of the cpu frequency change event
     * @since 3.0
     */
    default String eventCpuFrequency() {
        return "power_cpu_frequency"; //$NON-NLS-1$
    }

    /**
     * Get the name of the kernel event marking the entry of the complete IRQ
     * execution. This event is different from {@link #eventIrqHandlerEntry()}
     * and {@link #eventSoftIrqEntry()}. The latter mark the entry to the
     * hardware or software handler. Here this event is at a higher level and
     * may encompass both harware and software IRQs.
     *
     * @return The name of the irq entry function
     * @since 3.1
     */
    default String eventIrqEntry() {
        return "do_IRQ_entry"; //$NON-NLS-1$
    }

    /**
     * Get the name of the kernel event marking the exit of the complete IRQ
     * execution. This event is different from {@link #eventIrqHandlerExit()}
     * and {@link #eventSoftIrqExit()}. The latter mark the exit to the hardware
     * or software handler. Here this event is at a higher level and may
     * encompass both harware and software IRQs.
     *
     * @return The name of the irq exit function
     * @since 3.1
     */
    default String eventIrqExit() {
        return "do_IRQ_return"; //$NON-NLS-1$
    }

    /**
     * Get the name of the kernel events marking the entry to a network packet
     * reception context. The matching return events can be obtained with
     * {@link #eventsNetworkReceiveExit()}. The packet reception context will
     * typically include the packet reception, with one of
     * {@link #eventsNetworkReceive()} events and the wakeup events caused by
     * the reception.
     *
     * @return The list of events marking the beginning of a packet reception
     *         phase
     * @since 3.1
     */
    default Collection<String> eventsNetworkReceiveEntry() {
        return Collections.emptySet();
    }

    /**
     * Get the name of the kernel event marking the return of a network packet
     * reception code.
     *
     * @return The list of events marking the end of a packet reception phase
     * @since 3.1
     */
    default Collection<String> eventsNetworkReceiveExit() {
        return Collections.emptySet();
    }

}
