/* --COPYRIGHT--,ESD
 *  Copyright (c) 2008-2017 Texas Instruments Incorporated
 *  This program and the accompanying materials are made available under the
 *  terms of the Eclipse Public License v1.0 and Eclipse Distribution License
 *  v. 1.0 which accompanies this distribution. The Eclipse Public License is
 *  available at http://www.eclipse.org/legal/epl-v10.html and the Eclipse
 *  Distribution License is available at
 *  http://www.eclipse.org/org/documents/edl-v10.php.
 *
 *  Contributors:
 *      Texas Instruments - initial implementation
 * --/COPYRIGHT--*/
/*
 *  ======== LoggerBuf.xdc ========
 */

/*!
 *  ======== LoggerBuf ========
 *  A logger which stores `Log` events in a buffer.
 *
 *  This module provides a logger which captures `{@link Log}` events to a
 *  buffer in realtime. The `Log` events stored in the buffer are
 *  unformatted; `Log` event formatting is deferred until some client reads
 *  the raw event data from the buffer. You can use
 *  `{@link #flush LoggerBuf_flush()}` to process the `Log` events stored
 *  in the buffer and stream the formatted output to stdout
 *  (via `{@link System#printf}`).  Alternatively, you can read a raw event
 *  (via `{@link #getNextEntry}`) and send it to another client that
 *  has the resources to format the event for display.
 *
 *  The implementation of this logger is fast with minimal stack usage
 *  making it appropriate for a realtime application.
 *  This logger writes all `Log` events to a circular buffer.  As a
 *  result, the execution time of all `Log` methods bound to this type
 *  of logger are deterministic (and quite short) because there are no
 *  additional memory allocation calls after the circular buffer was
 *  allocated.
 *
 *  If this logger is used in a preemptive environment, then an appropriate
 *  gate must be assigned to the module. For example, if events are generated
 *  from an interrupt context, then a gate that disables interrupts
 *  must be used.
 *
 *  @p(code)
 *  var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
 *  LoggerBuf.common$.gate = ...some gate instance...
 *  @p
 *
 *  If the buffer type is circular, the log buffer of size
 *  `{@link #numEntries}` contains the last `numEntries` of `Log` events. If
 *  the buffer type is fixed, the log buffer contains the first
 *  `numEntries` events.
 *
 *  LoggerBuf supports routing of 'STATUS' events (errors and warnings) to a
 *  separate ILogger instance. This is helpful in preserving these critical
 *  events, which may otherwise be overwritten by lower priority events. This
 *  feature is disabled by default. See {@link #statusLogger}.
 *
 *  LoggerBuf implements the {@link IFilterLogger} interface and
 *  optionally supports filtering of events based on their detail level. This
 *  feature is disabled by default. See {@link IFilterLogger}.
 *
 *  @a(Examples)
 *  Configuration example: The following XDC configuration statements
 *  create a logger instance, assign it as the default logger for all
 *  modules, and enable `USER1` logging in all modules of the package
 *  `my.pkg`. See the `{@link Diags#setMaskMeta Diags.setMaskMeta()}` function
 *  for details on specifying the module names.
 *
 *  @p(code)
 *  var Defaults = xdc.useModule('xdc.runtime.Defaults');
 *  var Diags = xdc.useModule('xdc.runtime.Diags');
 *  var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
 *
 *  LoggerBuf.enableFlush = true;
 *  var LoggerBufParams = new LoggerBuf.Params();
 *  LoggerBufParams.exitFlush = true;
 *  Defaults.common$.logger = LoggerBuf.create(LoggerBufParams);
 *  Diags.setMaskMeta("my.pkg.%", Diags.USER1, Diags.RUNTIME_ON);
 *  @p
 */

@ModuleStartup      /* Initialize static instances */
@InstanceFinalize   /* this mod has cleanup fxn when instances are deleted */
@InstanceInitError  /* instance create can fail */
@Gated

module LoggerBuf inherits IFilterLogger {

    /*!
     *  ======== BufType ========
     *  Type of log buffer
     */
    enum BufType {
        BufType_CIRCULAR,  /*! The log buffer wraps, overwriting old entries */
        BufType_FIXED      /*! The log buffer halts collection when full */
    };

    metaonly struct BasicView {
        String label;
        Int lastSerial;
        UInt numEntries;
        String type;
        Bool enabledFlag;
    };

    metaonly struct RecordView {
        Int     serial;
        Long    timestampRaw;
        String  modName;
        String  text;
        Int     eventId;
        String  eventName;
        IArg    arg0;
        IArg    arg1;
        IArg    arg2;
        IArg    arg3;
        IArg    arg4;
        IArg    arg5;
        IArg    arg6;
        IArg    arg7;
    }

    /*!
     *  ======== rovViewInfo ========
     *  @_nodoc
     */
    @Facet
    metaonly config xdc.rov.ViewInfo.Instance rovViewInfo =
        xdc.rov.ViewInfo.create({
            viewMap: [
                ['Basic',
                    {
                        type: xdc.rov.ViewInfo.INSTANCE,
                        viewInitFxn: 'viewInitBasic',
                        structName: 'BasicView'
                    }
                ],
                ['Records',
                    {
                        type: xdc.rov.ViewInfo.INSTANCE_DATA,
                        viewInitFxn: 'viewInitRecords',
                        structName: 'RecordView'
                    }
                ]
            ]
        });

    /*!
     *  ======== StopModeData ========
     *  Data added to the RTA MetaData file to support stop mode RTA
     */
    @XmlDtd metaonly struct StopModeData {
        String bufferSymbol;
        Int bufferSize;
    }

    /*!
     *  ======== E_badLevel ========
     *  Error raised if get or setFilterLevel receives a bad level value
     */
    config Error.Id E_badLevel =
        {msg: "E_badLevel: Bad filter level value: %d"};

    /*!
     *  ======== TimestampProxy ========
     *  User supplied time-stamp proxy
     *
     *  This proxy allows `LoggerBuf` to use a timestamp server different
     *  from the server used by `{@link xdc.runtime.Timestamp}`. However, if
     *  not supplied by a user, this proxy defaults to whichever timestamp
     *  server is used by `Timestamp`.
     */
    proxy TimestampProxy inherits ITimestampClient;

    /*!
     *  ======== enableFlush ========
     *  Flush all logs at system exit
     */
    config Bool enableFlush = false;

    /*!
     *  ======== statusLogger ========
     *  Route all 'STATUS' (error and warning) events to this logger.
     *
     *  If a statusLogger is specified, all LoggerBuf instances will check to 
     *  determine if any of the events they receive are errors or warnings (if 
     *  their diags mask includes the STATUS category), and will log these 
     *  events to the statusLogger. 
     *
     *  Error events are infrequent, but it's generally critical that they be 
     *  seen. In a typical system, non-error events easily outnumber any error
     *  events, and the logger is likely to wrap, overwriting any error events.
     *  To protect these events from being overwritten and lost, they can be 
     *  sent to their own separate logger to preserve them.
     *
     *  The default value is null, indicating that the STATUS events will just
     *  be logged by the logger they were sent to.
     */
    config ILogger.Handle statusLogger = null;

    /*!
     *  ======== level1Mask ========
     *  Mask of diags categories whose initial filtering level is Diags.LEVEL1
     *
     *  See '{@link #level4Mask}' for details.
     */
    config Diags.Mask level1Mask = 0;

    /*!
     *  ======== level2Mask ========
     *  Mask of diags categories whose initial filtering level is Diags.LEVEL2
     *
     *  See '{@link #level4Mask}' for details.
     */
    config Diags.Mask level2Mask = 0;
    
    /*!
     *  ======== level3Mask ========
     *  Mask of diags categories whose initial filtering level is Diags.LEVEL3
     *
     *  See '{@link #level4Mask}' for details.
     */
    config Diags.Mask level3Mask = 0;
    
    /*!
     *  ======== level4Mask ========
     *  Mask of diags categories whose initial filtering level is Diags.LEVEL4
     *
     *  If `{@link IFilterLogger.filterByLevel}` is `true`, then all
     *  `LoggerBuf` instances will filter incoming events based on their
     *  event level.
     *
     *  The `LoggerBuf` module allows for specifying a different filter level
     *  for every `Diags` bit. These filtering levels are module wide;
     *  `LoggerBuf` does not support specifying the levels on a per-instance
     *  basis.
     *
     *  The `{@link IFilterLogger.setFilterLevel}` function can be used to
     *  change the filtering levels at runtime.
     *
     *  The default filtering levels are assigned using the `level1Mask` -
     *  `level4Mask` config parameters. These are used to specify, for each of
     *  the four event levels, the set of bits which should filter at that 
     *  level by default.
     *
     *  The default filtering configuration sets the filter level to 
     *  `Diags.LEVEL4` for all logging-related diags bits so that all events
     *  are logged by default.
     */
    config Diags.Mask level4Mask = Diags.ALL_LOGGING;

    /*!
     *  ======== flushAll ========
     *  Flush logs of all instances that set `exitFlush` to true
     *
     *  The user is responsible for making sure that no `LoggerBuf` instances
     *  are created or deleted during the execution of this function.
     */
    Void flushAll();

    /*!
     *  ======== flushAllInternal ========
     *  @_nodoc
     */
    Void flushAllInternal(Int stat);

    /*!
     *  ======== initDecoder ========
     * @_nodoc
     *  Initialize the LoggerBufDecoder for use in the LoggerBuf 'Records' ROV
     *  view.
     */
    function initDecoder();

instance:
    /*!
     *  ======== create ========
     *  Create a `LoggerBuf` logger
     *
     *  @see LoggerBuf#Params
     */
    create();

    /*!
     *  ======== numEntries ========
     *  Number of entries in buffer
     *
     *  Each entry is large enough to store one `Log` event containing up to
     *  4 optional arguments.  Events containing more than 4 arguments (such
     *  as those from `{@link Log#write5}`) use 2 entries.
     *
     *  `numEntries` must be a power of 2.
     */
    config UInt numEntries = 64;

    /*!
     *  ======== bufType ========
     *  Log buffer type
     */
    config BufType bufType = BufType_CIRCULAR;

    /*!
     *  ======== exitFlush ========
     *  Flush log at system exit
     *
     *  Only used when module parameter `{@link #enableFlush}` is `true`.
     */
    config Bool exitFlush = false;

    /*!
     *  ======== bufSection ========
     *  Section name for the buffer managed by the static instance.
     *
     *  The default section is the 'dataSection' in the platform.
     */
    metaonly config String bufSection = null;

    /*!
     *  ======== bufHeap ========
     *  The heap that contains the `Log` buffer for dynamic instances.
     *
     *  The default value `null` means the buffer will be allocated from
     *  the `{@link Memory#defaultHeapInstance}` heap.
     */
    config IHeap.Handle bufHeap = null;

    /*!
     *  ======== reset ========
     *  Reset a log to empty state and enable it
     *
     *  @a(WARNING)  This method is not synchronized with other instance
     *  methods and, as a result, it must never be called when there is a
     *  chance that another instance method is currently in operation or
     *  when another method on this instance may preempt this call.
     */
    Void reset();

    /*!
     *  ======== flush ========
     *  Read, clear, and output the contents of the log
     *
     *  This method reads, clears, and "prints" each `Log` event (via
     *  `{@link System#printf}`) in the log.
     */
    Void flush();

    /*!
     *  ======== getNextEntry ========
     *  Fills the passed `{@link Log#EventRec}` with the next entry in the log.
     *
     *  This function is used to read and clear `Log` events from the
     *  buffer maintained by the `LoggerBuf` instance. The `Log` event can
     *  then be transmitted and displayed on a host.
     *
     *  A read pointer is maintained in the `LoggerBuf` instance and
     *  points to the next record to read.  Entries are not necessarily
     *  returned in chronological order, since buffers of type
     *  `{@link #BufType_CIRCULAR}` can wrap.
     *
     *  @param(evtRec) pointer to a supplied `EventRec` object where the next
     *                 entry in the log is copied to
     *
     *  @a(returns)
     *  This function reports the number of entries actually read. The only
     *  values that can be returned are:
     *  @p(blist)
     *      - 0   no more entries to read
     *      - 1 or 2 read a complete entry written by `write4` or `write8`
     *      - -1  cleared an incomplete/overwritten entry, more entries to read
     */
    Int getNextEntry(Log.EventRec *evtRec);

internal:

    Bool filterOutEvent(Diags.Mask mask);

    const Int8 FULL = -1;
    const Int8 WRAP = 0;

    const Int8 NEXT = 1;

    struct Entry {
        Types.Timestamp64 tstamp;
        Bits32 serial;
        Types.Event evt;
        IArg arg1;
        IArg arg2;
        IArg arg3;
        IArg arg4;
    };

    struct Module_State {
        Diags.Mask level1;
        Diags.Mask level2;
        Diags.Mask level3;
    };

    struct Instance_State {
        IHeap.Handle bufHeap;
        Entry entryArr[];
        Entry *curEntry;
        Entry *endEntry;
        Entry *readEntry;
        Bits32 serial;
        UInt16 numEntries;
        Int8 advance;
        Bool enabled;
        Bool flush;
    };

}
