/*******************************************************************************
 * Copyright (c) 2011-2014 Ericsson, Ecole Polytechnique de Montreal and others
 *
 * 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: Matthew Khouzam - Initial API and implementation
 * Contributors: Simon Marchi - Initial API and implementation
 *******************************************************************************/

package org.eclipse.tracecompass.internal.ctf.core.event;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.ctf.core.event.IEventDeclaration;
import org.eclipse.tracecompass.ctf.core.event.IEventDefinition;
import org.eclipse.tracecompass.ctf.core.event.scope.IDefinitionScope;
import org.eclipse.tracecompass.ctf.core.event.scope.ILexicalScope;
import org.eclipse.tracecompass.ctf.core.event.scope.LexicalScope;
import org.eclipse.tracecompass.ctf.core.event.types.Definition;
import org.eclipse.tracecompass.ctf.core.event.types.ICompositeDefinition;
import org.eclipse.tracecompass.ctf.core.event.types.IDefinition;
import org.eclipse.tracecompass.ctf.core.event.types.StructDeclaration;
import org.eclipse.tracecompass.ctf.core.event.types.StructDefinition;
import org.eclipse.tracecompass.ctf.core.trace.ICTFPacketDescriptor;

/**
 * Representation of a particular instance of an event.
 */
public final class EventDefinition implements IDefinitionScope, IEventDefinition {

    // ------------------------------------------------------------------------
    // Attributes
    // ------------------------------------------------------------------------

    /**
     * The corresponding event declaration.
     */
    private final IEventDeclaration fDeclaration;

    /**
     * The timestamp of the current event.
     */
    private final long fTimestamp;

    private final ICompositeDefinition fEventHeaderDefinition;

    /**
     * The event context structure definition.
     */
    private final ICompositeDefinition fEventContext;

    private final ICompositeDefinition fStreamContext;

    private final ICompositeDefinition fPacketContext;

    /**
     * The event fields structure definition.
     */
    private final ICompositeDefinition fFields;

    /**
     * The current cpu, could be @link {@link IPacketHeader#UNKNOWN_CPU}
     */
    private final int fCpu;

    private final @NonNull Map<String, Object> fPacketAttributes;

    // ------------------------------------------------------------------------
    // Constructors
    // ------------------------------------------------------------------------

    /**
     * Constructs an event definition.
     *
     * @param declaration
     *            The corresponding event declaration
     * @param cpu
     *            The cpu source of the event. You can use UNKNOWN_CPU if it is
     *            not known.
     * @param timestamp
     *            event timestamp
     * @param eventHeaderDefinition
     *            The event header definition, can be null if there is no header
     *            definition
     * @param eventContext
     *            The event context
     * @param packetContext
     *            the packet context (the one with content size, not magic
     *            number)
     * @param streamContext
     *            the stream context
     * @param fields
     *            The event fields
     * @param packetDescriptor
     *            descriptor of the packet containing this event
     * @since 2.0
     */
    public EventDefinition(IEventDeclaration declaration,
            int cpu,
            long timestamp,
            ICompositeDefinition eventHeaderDefinition,
            ICompositeDefinition streamContext,
            ICompositeDefinition eventContext,
            ICompositeDefinition packetContext,
            ICompositeDefinition fields,
            @Nullable ICTFPacketDescriptor packetDescriptor) {
        fDeclaration = declaration;
        fEventHeaderDefinition = eventHeaderDefinition;
        fCpu = cpu;
        fTimestamp = timestamp;
        fFields = fields;
        fEventContext = eventContext;
        fPacketContext = packetContext;
        fStreamContext = streamContext;
        fPacketAttributes = packetDescriptor != null ? packetDescriptor.getAttributes() : Collections.emptyMap();
    }

    // ------------------------------------------------------------------------
    // Getters/Setters/Predicates
    // ------------------------------------------------------------------------

    @Override
    public ILexicalScope getScopePath() {
        String eventName = fDeclaration.getName();
        if (eventName == null) {
            return null;
        }
        ILexicalScope myScope = ILexicalScope.EVENT.getChild(eventName);
        if (myScope == null) {
            myScope = new LexicalScope(ILexicalScope.EVENT, eventName);
        }
        return myScope;
    }

    @Override
    public IEventDeclaration getDeclaration() {
        return fDeclaration;
    }

    @Override
    public ICompositeDefinition getEventHeader() {
        return fEventHeaderDefinition;
    }

    @Override
    public ICompositeDefinition getFields() {
        return fFields;
    }

    @Override
    public ICompositeDefinition getEventContext() {
        return fEventContext;
    }

    @Override
    public ICompositeDefinition getStreamContext() {
        return fStreamContext;
    }

    @Override
    public ICompositeDefinition getContext() {

        /* Most common case so far */
        if (fStreamContext == null) {
            return fEventContext;
        }

        /* streamContext is not null, but the context of the event is null */
        if (fEventContext == null) {
            return fStreamContext;
        }

        // TODO: cache if this is a performance issue

        /* The stream context and event context are assigned. */
        StructDeclaration mergedDeclaration = new StructDeclaration(1);

        List<Definition> fieldValues = new ArrayList<>();

        /* Add fields from the stream */
        List<@NonNull String> fieldNames = fStreamContext.getFieldNames();
        for (String fieldName : fieldNames) {
            Definition definition = fStreamContext.getDefinition(fieldName);
            mergedDeclaration.addField(fieldName, definition.getDeclaration());
            fieldValues.add(definition);
        }

        /*
         * Add fields from the event context, overwrite the stream ones if
         * needed.
         */
        for (String fieldName : fEventContext.getFieldNames()) {
            Definition definition = fEventContext.getDefinition(fieldName);
            mergedDeclaration.addField(fieldName, definition.getDeclaration());
            if (fieldNames.contains(fieldName)) {
                fieldValues.set((fieldNames.indexOf(fieldName)), definition);
            } else {
                fieldValues.add(definition);
            }
        }
        return new StructDefinition(mergedDeclaration, this, "context", //$NON-NLS-1$
                fieldValues.toArray(new Definition[fieldValues.size()]));
    }

    @Override
    public ICompositeDefinition getPacketContext() {
        return fPacketContext;
    }

    @Override
    public int getCPU() {
        return fCpu;
    }

    @Override
    public long getTimestamp() {
        return fTimestamp;
    }

    @Override
    public Map<String, Object> getPacketAttributes() {
        return fPacketAttributes;
    }

    // ------------------------------------------------------------------------
    // Operations
    // ------------------------------------------------------------------------

    @Override
    public IDefinition lookupDefinition(String lookupPath) {
        if (lookupPath.equals("context")) { //$NON-NLS-1$
            return fEventContext;
        } else if (lookupPath.equals("fields")) { //$NON-NLS-1$
            return fFields;
        } else {
            return null;
        }
    }

    @Override
    public String toString() {
        Iterable<String> list;
        StringBuilder retString = new StringBuilder();
        final String cr = System.getProperty("line.separator");//$NON-NLS-1$

        retString.append("Event type: ").append(fDeclaration.getName()).append(cr); //$NON-NLS-1$
        retString.append("Timestamp: ").append(Long.toString(fTimestamp)).append(cr); //$NON-NLS-1$

        if (fEventContext != null) {
            list = fEventContext.getFieldNames();

            for (String field : list) {
                retString.append(field).append(" : ").append(fEventContext.getDefinition(field).toString()).append(cr); //$NON-NLS-1$
            }
        }

        if (fFields != null) {
            list = fFields.getFieldNames();

            for (String field : list) {
                retString.append(field).append(" : ").append(fFields.getDefinition(field).toString()).append(cr); //$NON-NLS-1$
            }
        }

        return retString.toString();
    }

}
