/*******************************************************************************
 * Copyright (c) 2017 Ericsson
 *
 * 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
 *******************************************************************************/

package org.eclipse.tracecompass.incubator.internal.uftrace.core.trace;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;

import org.apache.commons.io.FilenameUtils;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.analysis.os.linux.core.event.aspect.LinuxPidAspect;
import org.eclipse.tracecompass.analysis.os.linux.core.event.aspect.LinuxTidAspect;
import org.eclipse.tracecompass.incubator.internal.uftrace.core.Activator;
import org.eclipse.tracecompass.incubator.internal.uftrace.core.trace.SymParser.Symbol;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.event.ITmfEventType;
import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
import org.eclipse.tracecompass.tmf.core.event.aspect.TmfBaseAspects;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.project.model.ITmfPropertiesProvider;
import org.eclipse.tracecompass.tmf.core.symbols.ISymbolProvider;
import org.eclipse.tracecompass.tmf.core.symbols.ISymbolProviderFactory;
import org.eclipse.tracecompass.tmf.core.symbols.TmfResolvedSymbol;
import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceKnownSize;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceWithPreDefinedEvents;
import org.eclipse.tracecompass.tmf.core.trace.TmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TraceValidationStatus;
import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;

/**
 * Trace with the following data
 * <ul>
 * <li>info : various information about uftrace and running process</li>
 * <li>task.txt : task and session information</li>
 * <li>sid-<SESSION_ID>.map : memory mapping for a session</li>
 * <li>[PROGRAM].sym : (function) symbol address and name</li>
 * <li>[TID].dat : trace data for each task of given <TID></li>
 * <li>kernel_header : kernel ftrace header info (only if kernel tracing was
 * used)</li>
 * <li>kallsyms : kernel symbol information (ditto)</li>
 * <li>kernel-cpuX.dat : per-cpu kernel tracing data (ditto)</li>
 * </ul>
 *
 * @author Matthew Khouzam
 */
public class Uftrace extends TmfTrace implements ITmfPropertiesProvider,
        ITmfTraceKnownSize, ITmfTraceWithPreDefinedEvents {

    private Collection<DatParser> fDats = new ArrayList<>();
    private Map<Long, MapParser> fMap = new HashMap<>();
    private Map<String, SymParser> fSyms = new HashMap<>();
    private TaskParser fTasks;
    private TmfLongLocation fCurrentLoc = new TmfLongLocation(0L);
    private InfoParser fInfo;

    private long fSize;

    private final ISymbolProvider fSymbolProvider = new UfTraceSymbolProvider();

    private final @NonNull TidAspect fTidAspect = new TidAspect();
    private final @NonNull PidAspect fPidAspect = new PidAspect();
    private final @NonNull ExecAspect fExecAspect = new ExecAspect();
    private @Nullable String fHostId = null;

    @Override
    public Iterable<ITmfEventAspect<?>> getEventAspects() {
        return ImmutableList.of(TmfBaseAspects.getTimestampAspect(), TmfBaseAspects.getEventTypeAspect(),
                new ITmfEventAspect<Integer>() {

                    @Override
                    public String getName() {
                        return "depth"; //$NON-NLS-1$
                    }

                    @Override
                    public String getHelpText() {
                        return ""; //$NON-NLS-1$
                    }

                    @Override
                    public @Nullable Integer resolve(ITmfEvent event) {
                        Object fieldValue = event.getContent().getValue();
                        if (fieldValue instanceof DatEvent) {
                            return ((DatEvent) fieldValue).getDepth();
                        }
                        return null;
                    }
                }, new ITmfEventAspect<String>() {

                    @Override
                    public String getName() {
                        return "Address"; //$NON-NLS-1$
                    }

                    @Override
                    public String getHelpText() {
                        return ""; //$NON-NLS-1$
                    }

                    @Override
                    public @Nullable String resolve(ITmfEvent event) {
                        if (event.getContent().getValue() instanceof DatEvent) {
                            DatEvent datEvent = (DatEvent) event.getContent().getValue();
                            TmfResolvedSymbol symbol = fSymbolProvider.getSymbol(datEvent.getTid(), 0, datEvent.getAddress());
                            if (symbol != null) {
                                return symbol.getSymbolName();
                            }
                        }
                        return null;
                    }
                }, getTidAspect(), getPidAspect(), getExecAspect()

        );
    }

    @Override
    public IStatus validate(IProject project, String path) {
        File dir = new File(path);
        int confidence = 0;
        if (dir.isDirectory()) {
            confidence += 5;
            List<File> data = Arrays.asList(dir.listFiles());
            boolean hasDat = false;
            boolean hasMap = false;
            boolean hasSym = false;
            for (File file : data) {
                String extension = FilenameUtils.getExtension(file.getName());
                if (extension.equals("dat")) { //$NON-NLS-1$
                    try {
                        // TODO: Also support the perf-cpu data. For now, it
                        // does not contain uftrace data
                        if (file.getName().startsWith("perf-cpu")) { //$NON-NLS-1$
                            continue;
                        }
                        DatParser dp = new DatParser(file);
                        // read first event (really check magic number header)
                        dp.iterator().next();
                        confidence += 4;
                        hasDat = true;
                    } catch (IllegalArgumentException e) {
                        // we don't want a failing trace
                        return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "dat parsing error", e); //$NON-NLS-1$
                    }

                }
                if (extension.equals("map")) { //$NON-NLS-1$
                    try {
                        if (MapParser.create(file) != null) {
                            confidence += 4;
                        }
                        hasMap = true;
                    } catch (IOException e) {
                        // we don't want a failing trace
                        return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "map parsing error", e); //$NON-NLS-1$
                    }
                }
                if (extension.equals("sym")) { //$NON-NLS-1$
                    hasSym = true;
                    confidence += 3;
                }
            }
            if (hasMap && hasDat && hasSym && confidence > 10) {
                return new TraceValidationStatus(confidence, Activator.class.getCanonicalName());
            }
        }
        return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Most probably not a UFTrace"); //$NON-NLS-1$
    }

    @Override
    public void initTrace(IResource resource, String path, Class<? extends ITmfEvent> type) throws TmfTraceException {
        File dir = new File(path);
        if (!dir.isDirectory()) {
            throw new TmfTraceException("trace is not a directory"); //$NON-NLS-1$
        }
        super.initTrace(resource, path, type);
        for (File child : dir.listFiles()) {
            String name = child.getName();
            try {
                if (name.endsWith(".dat")) { //$NON-NLS-1$
                    // TODO: Also support the perf-cpu data. For now, it does
                    // not contain uftrace data
                    if (name.startsWith("perf-cpu")) { //$NON-NLS-1$
                        continue;
                    }
                    fSize += child.length();
                    fDats.add(new DatParser(child));
                } else if (name.endsWith(".map")) { //$NON-NLS-1$
                    MapParser create = MapParser.create(child);
                    if (create != null) {
                        fMap.put(create.getSessionId(), create);
                    }
                } else if (name.endsWith(".sym")) { //$NON-NLS-1$
                    fSyms.put(name.substring(0, name.length() - 4), SymParser.parse(child));
                } else if (name.equals("task.txt")) { //$NON-NLS-1$
                    fTasks = new TaskParser(child);
                } else if (name.equals("info")) { //$NON-NLS-1$
                    fInfo = InfoParser.parse(child);
                } else if (name.equals("hostid")) { //$NON-NLS-1$
                    /*
                     * A 'hostid' file can be added which contains only one line
                     * with the host ID in it. This can be used to correlate
                     * with some other traces' data like an lttng kernel trace
                     */
                    List<String> fileLines = Files.readAllLines(child.toPath());
                    if (!fileLines.isEmpty()) {
                        fHostId = fileLines.get(0);
                    }
                }
            } catch (IOException e) {
                throw new TmfTraceException(e.getMessage(), e);
            }
        }
    }

    @Override
    public ITmfLocation getCurrentLocation() {
        return fCurrentLoc;
    }

    @Override
    public double getLocationRatio(ITmfLocation location) {
        return (long) location.getLocationInfo() / fSize;
    }

    @Override
    public ITmfContext seekEvent(ITmfLocation location) {
        UfContext context = new UfContext(fDats, this);
        if (location == null) {
            return context;
        }
        if (location instanceof TmfLongLocation) {
            TmfLongLocation longLocation = (TmfLongLocation) location;
            if (longLocation.getLocationInfo().longValue() == 0) {
                return context;
            }
            while (context.getLocation() != null && Long.compare(longLocation.getLocationInfo(), Objects.requireNonNull(context.getLocation()).getLocationInfo()) >= 0) {
                ITmfEvent next = context.getNext();
                if (next == null) {
                    break;
                }
                updateAttributes(context, next);
                if (context.getLocation() == null) {
                    return context;
                }
            }
        }
        return context;
    }

    @Override
    public ITmfContext seekEvent(double ratio) {
        return seekEvent(new TmfLongLocation((long) (ratio * fSize)));
    }

    @Override
    public ITmfEvent parseEvent(@Nullable ITmfContext ctx) {
        ITmfContext context = ctx;
        if (context == null) {
            context = seekEvent(0);
        }
        if (ctx instanceof UfContext) {
            UfContext ufContext = (UfContext) ctx;
            ITmfEvent tmfEvent = ufContext.getNext();
            if (tmfEvent != null) {
                fCurrentLoc = new TmfLongLocation(fCurrentLoc.getLocationInfo() + Long.BYTES * 2);
                ctx.setLocation(fCurrentLoc);
                updateAttributes(context, tmfEvent);
                return tmfEvent;
            }
        }
        return null;
    }

    @Override
    public Set<@NonNull ? extends ITmfEventType> getContainedEventTypes() {
        return UfEventType.TYPES;
    }

    @Override
    public int size() {
        return (int) (fSize / 1024);
    }

    @Override
    public int progress() {
        return (int) (fCurrentLoc.getLocationInfo() / 1024);
    }

    @Override
    public @NonNull String getHostId() {
        if (fHostId != null) {
            return fHostId;
        }
        return super.getHostId();
    }

    /**
     * Get the symbol provider for this trace
     *
     * @return the symbol provider
     */
    public ISymbolProvider getSymbolProvider() {
        return fSymbolProvider;
    }

    /**
     * TID aspect for UFTrace
     *
     * @author Matthew Khouzam
     */
    public final class TidAspect extends LinuxTidAspect {
        @Override
        public @Nullable Integer resolve(ITmfEvent event) {
            if (event.getContent().getValue() instanceof DatEvent) {
                DatEvent datEvent = (DatEvent) event.getContent().getValue();
                return datEvent.getTid();
            }
            return null;
        }
    }

    /**
     * PID aspect for UFTrace
     *
     * @author Matthew Khouzam
     */
    public final class PidAspect extends LinuxPidAspect {
        @Override
        public @Nullable Integer resolve(ITmfEvent event) {
            if (event.getContent().getValue() instanceof DatEvent) {
                DatEvent datEvent = (DatEvent) event.getContent().getValue();
                int tid = datEvent.getTid();
                return fTasks.getPid(tid);
            }
            return null;
        }
    }

    /**
     * Executable name aspect for UFTrace
     *
     * @author Matthew Khouzam
     */
    public final class ExecAspect implements ITmfEventAspect<String> {
        @Override
        public @NonNull String getName() {
            return "Executable"; //$NON-NLS-1$
        }

        @Override
        public @NonNull String getHelpText() {
            return ""; //$NON-NLS-1$
        }

        @Override
        public @Nullable String resolve(@NonNull ITmfEvent event) {
            if (event.getContent().getValue() instanceof DatEvent) {
                DatEvent datEvent = (DatEvent) event.getContent().getValue();
                int tid = datEvent.getTid();
                return fTasks.getExecName(tid);
            }
            return null;
        }
    }

    /**
     * Alleged symbol provider factory
     *
     * @author Matthew Khouzam
     *
     */
    public static class UfTraceSymbolProviderAllegedFactory implements ISymbolProviderFactory {

        @Override
        public @Nullable ISymbolProvider createProvider(@NonNull ITmfTrace trace) {
            if (trace instanceof Uftrace) {
                return ((Uftrace) trace).getSymbolProvider();
            }
            return null;
        }
    }

    @Override
    public @NonNull Map<@NonNull String, @NonNull String> getProperties() {
        if(fInfo == null) {
            return Collections.emptyMap();
        }
        Map<@NonNull String, @NonNull String> properties = new LinkedHashMap<>();
        properties.put("version", String.valueOf(fInfo.getVersion())); //$NON-NLS-1$
        properties.put("address length", String.valueOf(fInfo.getAddressSize())); //$NON-NLS-1$
        properties.put("endianness", String.valueOf(fInfo.getByteOrder())); //$NON-NLS-1$
        properties.put("maximum depth", String.valueOf(fInfo.getMaxDepth())); //$NON-NLS-1$
        properties.put("feature bit mask", Long.toBinaryString(fInfo.getFeatures())); //$NON-NLS-1$
        String hostId = fHostId;
        if (hostId != null) {
            properties.put("host ID", hostId); //$NON-NLS-1$
        }
        properties.putAll(fInfo.getData());
        return properties;
    }

    /**
     * get the tasks parser
     *
     * @return The tasks parser
     */
    public TaskParser getTasks() {
        return fTasks;
    }

    /**
     * Get the aspect to retrieve the executable name from a uftrace event
     *
     * @return The executable name aspect
     */
    public @NonNull ExecAspect getExecAspect() {
        return fExecAspect;
    }

    /**
     * Get the aspect to retrieve the PID of a uftrace event
     *
     * @return the pid aspect
     */
    public @NonNull PidAspect getPidAspect() {
        return fPidAspect;
    }

    /**
     * Get the aspect to retrieve the TID of a uftrace event
     *
     * @return the TID aspect
     */
    public @NonNull TidAspect getTidAspect() {
        return fTidAspect;
    }

    /**
     * overly complicated, should clean up
     *
     * @author Matthew Khouzam
     *
     */
    private class UfTraceSymbolProvider implements ISymbolProvider {
        @Override
        public TmfResolvedSymbol getSymbol(int tid, long timestamp, long address) {
            String execName = fTasks.getExecName(tid);
            if (execName == null) {
                return new TmfResolvedSymbol(address, "0x" + Long.toHexString(address)); //$NON-NLS-1$
            }
            Long session = fTasks.getSessName(tid);
            if (session == null) {
                return new TmfResolvedSymbol(address, "0x" + Long.toHexString(address)); //$NON-NLS-1$
            }
            MapParser mapParser = fMap.get(session);
            if (mapParser == null) {
                return new TmfResolvedSymbol(address, "0x" + Long.toHexString(address)); //$NON-NLS-1$
            }
            Entry<Long, MapEntry> key = mapParser.getData().floorEntry(address);
            if (key == null) {
                return new TmfResolvedSymbol(address, "0x" + Long.toHexString(address)); //$NON-NLS-1$
            }
            long offset = address - key.getValue().getAddrLow();
            String pathName = key.getValue().getPathName();
            String substring = pathName.substring(pathName.lastIndexOf(File.separator) + 1);
            SymParser sym = fSyms.get(substring);
            if (sym == null) {
                return new TmfResolvedSymbol(address, pathName + ":0x" + Long.toHexString(address)); //$NON-NLS-1$
            }
            Entry<Long, Symbol> floorEntry = sym.getMap().floorEntry(offset);
            if (floorEntry != null) {
                Symbol value = floorEntry.getValue();
                if (value != null) {
                    String name = String.valueOf(value.getName());
                    return new TmfResolvedSymbol(address, name);
                }
            }
            return new TmfResolvedSymbol(address, "0x" + Long.toHexString(address)); //$NON-NLS-1$
        }

        /* needed for ISymbolProvider */
        @Override
        public @NonNull ITmfTrace getTrace() {
            return (ITmfTrace) this;
        }

        @Override
        public void loadConfiguration(@Nullable IProgressMonitor monitor) {
            // do nothing
        }

        @Override
        public @Nullable TmfResolvedSymbol getSymbol(long address) {
            return getSymbol(Iterables.getFirst(fTasks.getTids(), -1), 0, address);
        }

    }

}
