/**********************************************************************
 * Copyright (c) 2014, 2016 Ericsson, École Polytechnique de Montréal
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Matthew Khouzam - Initial API and implementation
 *   Geneviève Bastien - Memory is per thread and only total is kept
 **********************************************************************/

package org.eclipse.tracecompass.internal.lttng2.ust.core.analysis.memory;

import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.analysis.os.linux.core.event.aspect.LinuxTidAspect;
import org.eclipse.tracecompass.lttng2.ust.core.trace.LttngUstTrace;
import org.eclipse.tracecompass.lttng2.ust.core.trace.layout.ILttngUstEventLayout;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider;
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;

import com.google.common.collect.ImmutableMap;

/**
 * State provider to track the memory of the threads using the UST libc wrapper
 * memory events.
 *
 * Attribute tree:
 *
 * <pre>
 * |- <TID number>
 * |  |- UST_MEMORY_MEMORY_ATTRIBUTE -> Memory Usage
 * |  |- UST_MEMORY_PROCNAME_ATTRIBUTE -> Process name
 * </pre>
 *
 * @author Matthew Khouzam
 * @author Geneviève Bastien
 */
public class UstMemoryStateProvider extends AbstractTmfStateProvider {

    /* Version of this state provider */
    private static final int VERSION = 2;

    private static final Long MINUS_ONE = Long.valueOf(-1);
    private static final Long ZERO = Long.valueOf(0);

    private static final int MALLOC_INDEX = 1;
    private static final int FREE_INDEX = 2;
    private static final int CALLOC_INDEX = 3;
    private static final int REALLOC_INDEX = 4;
    private static final int MEMALIGN_INDEX = 5;
    private static final int POSIX_MEMALIGN_INDEX = 6;

    /** Map of a pointer to a memory zone to the size of the memory */
    private final Map<Long, Long> fMemory = new HashMap<>();

    private final @NonNull ILttngUstEventLayout fLayout;
    private final @NonNull Map<String, Integer> fEventNames;

    /**
     * Constructor
     *
     * @param trace
     *            trace
     */
    public UstMemoryStateProvider(@NonNull ITmfTrace trace) {
        super(trace, "Ust:Memory"); //$NON-NLS-1$
        if (!(trace instanceof LttngUstTrace)) {
            fLayout = ILttngUstEventLayout.DEFAULT_LAYOUT;
        } else {
            fLayout = ((LttngUstTrace) trace).getEventLayout();
        }
        fEventNames = buildEventNames(fLayout);
    }

    private static @NonNull Map<String, Integer> buildEventNames(ILttngUstEventLayout layout) {
        ImmutableMap.Builder<String, Integer> builder = ImmutableMap.builder();
        builder.put(layout.eventLibcMalloc(), MALLOC_INDEX);
        builder.put(layout.eventLibcFree(), FREE_INDEX);
        builder.put(layout.eventLibcCalloc(), CALLOC_INDEX);
        builder.put(layout.eventLibcRealloc(), REALLOC_INDEX);
        builder.put(layout.eventLibcMemalign(), MEMALIGN_INDEX);
        builder.put(layout.eventLibcPosixMemalign(), POSIX_MEMALIGN_INDEX);
        return builder.build();
    }

    @Override
    protected void eventHandle(ITmfEvent event) {
        String name = event.getName();
        Integer index = fEventNames.get(name);
        int intIndex = (index == null ? -1 : index.intValue());

        switch (intIndex) {
        case MALLOC_INDEX: {
            Long ptr = (Long) event.getContent().getField(fLayout.fieldPtr()).getValue();
            if (ZERO.equals(ptr)) {
                return;
            }
            Long size = (Long) event.getContent().getField(fLayout.fieldSize()).getValue();
            setMem(event, ptr, size);
        }
            break;
        case FREE_INDEX: {
            Long ptr = (Long) event.getContent().getField(fLayout.fieldPtr()).getValue();
            if (ZERO.equals(ptr)) {
                return;
            }
            setMem(event, ptr, ZERO);
        }
            break;
        case CALLOC_INDEX: {
            Long ptr = (Long) event.getContent().getField(fLayout.fieldPtr()).getValue();
            if (ZERO.equals(ptr)) {
                return;
            }
            Long nmemb = (Long) event.getContent().getField(fLayout.fieldNmemb()).getValue();
            Long size = (Long) event.getContent().getField(fLayout.fieldSize()).getValue();
            setMem(event, ptr, size * nmemb);
        }
            break;
        case REALLOC_INDEX: {
            Long ptr = (Long) event.getContent().getField(fLayout.fieldPtr()).getValue();
            if (ZERO.equals(ptr)) {
                return;
            }
            Long newPtr = (Long) event.getContent().getField(fLayout.fieldInPtr()).getValue();
            Long size = (Long) event.getContent().getField(fLayout.fieldSize()).getValue();
            setMem(event, ptr, ZERO);
            setMem(event, newPtr, size);
        }
            break;
        case MEMALIGN_INDEX: {
            Long ptr = (Long) event.getContent().getField(fLayout.fieldPtr()).getValue();
            if (ZERO.equals(ptr)) {
                return;
            }
            Long size = (Long) event.getContent().getField(fLayout.fieldSize()).getValue();
            setMem(event, ptr, size);
        }
            break;
        case POSIX_MEMALIGN_INDEX: {
            Long ptr = (Long) event.getContent().getField(fLayout.fieldOutPtr()).getValue();
            if (ZERO.equals(ptr)) {
                return;
            }
            Long size = (Long) event.getContent().getField(fLayout.fieldSize()).getValue();
            setMem(event, ptr, size);
        }
            break;
        default:
            /* Ignore other event types */
            break;
        }

    }

    @Override
    public ITmfStateProvider getNewInstance() {
        return new UstMemoryStateProvider(getTrace());
    }

    @Override
    public LttngUstTrace getTrace() {
        return (LttngUstTrace) super.getTrace();
    }

    @Override
    public int getVersion() {
        return VERSION;
    }

    private static Long getVtid(ITmfEvent event) {
        /* We checked earlier that the "vtid" context is present */
        Integer tid = TmfTraceUtils.resolveIntEventAspectOfClassForEvent(event.getTrace(), LinuxTidAspect.class, event);
        if (tid == null) {
            return MINUS_ONE;
        }
        return tid.longValue();
    }

    private @Nullable String getProcname(ITmfEvent event) {
        ITmfEventField field = event.getContent().getField(fLayout.contextProcname());
        if (field == null) {
            return null;
        }
        return (String) field.getValue();
    }

    private void setMem(ITmfEvent event, Long ptr, Long size) {
        ITmfStateSystemBuilder ss = checkNotNull(getStateSystemBuilder());
        long ts = event.getTimestamp().toNanos();
        Long tid = getVtid(event);

        Long memoryDiff = size;
        /* Size is 0, it means it was deleted */
        if (ZERO.equals(size)) {
            Long memSize = fMemory.remove(ptr);
            if (memSize == null) {
                return;
            }
            memoryDiff = -memSize;
        } else {
            fMemory.put(ptr, size);
        }
        try {
            int tidQuark = ss.getQuarkAbsoluteAndAdd(tid.toString());
            int tidMemQuark = ss.getQuarkRelativeAndAdd(tidQuark, UstMemoryStrings.UST_MEMORY_MEMORY_ATTRIBUTE);

            ITmfStateValue prevMem = ss.queryOngoingState(tidMemQuark);
            /* First time we set this value */
            if (prevMem.isNull()) {
                String procName = getProcname(event);
                /*
                 * No tid/procname for the event for the event, added to a
                 * 'others' thread
                 */
                if (tid.equals(MINUS_ONE)) {
                    procName = UstMemoryStrings.OTHERS;
                }
                if (procName != null) {
                    int procNameQuark = ss.getQuarkRelativeAndAdd(tidQuark, UstMemoryStrings.UST_MEMORY_PROCNAME_ATTRIBUTE);
                    ss.modifyAttribute(ts, procName, procNameQuark);
                }
                prevMem = TmfStateValue.newValueLong(0);
            }

            long prevMemValue = prevMem.unboxLong();
            prevMemValue += memoryDiff.longValue();
            ss.modifyAttribute(ts, prevMemValue, tidMemQuark);
        } catch (TimeRangeException | StateValueTypeException e) {
            throw new IllegalStateException(e);
        }
    }

}
