/*
 * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.jfr.consumer;

import java.io.Closeable;
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;

import jdk.jfr.EventType;
import jdk.jfr.internal.MetadataDescriptor;
import jdk.jfr.internal.Type;
import jdk.jfr.internal.consumer.ChunkHeader;
import jdk.jfr.internal.consumer.RecordingInput;
import jdk.jfr.internal.consumer.RecordingInternals;

/**
 * A recording file.
 * <p>
 * The following example shows how read and print all events in a recording file.
 *
 * <pre>
 * <code>
 * try (RecordingFile recordingFile = new RecordingFile(Paths.get("recording.jfr"))) {
 *   while (recordingFile.hasMoreEvents()) {
 *     RecordedEvent event = recordingFile.readEvent();
 *     System.out.println(event);
 *   }
 * }
 * </code>
 * </pre>
 *
 * @since 9
 */
public final class RecordingFile implements Closeable {
    static{
        RecordingInternals.INSTANCE = new RecordingInternals() {
            public List<Type> readTypes(RecordingFile file) throws IOException {
                return file.readTypes();
            }

            public boolean isLastEventInChunk(RecordingFile file) {
                return file.isLastEventInChunk;
            }

            @Override
            public Object getOffsetDataTime(RecordedObject event, String name) {
                return event.getOffsetDateTime(name);
            }

            @Override
            public void sort(List<RecordedEvent> events) {
               Collections.sort(events, (e1, e2) -> Long.compare(e1.endTime, e2.endTime));
            }
        };
    }

    private boolean isLastEventInChunk;
    private final File file;
    private RecordingInput input;
    private ChunkParser chunkParser;
    private RecordedEvent nextEvent;
    private boolean eof;

    /**
     * Creates a recording file.
     *
     * @param file the path of the file to open, not {@code null}
     * @throws IOException if it's not a valid recording file, or an I/O error
     *         occurred
     * @throws NoSuchFileException if the {@code file} can't be located
     *
     * @throws SecurityException if a security manager exists and its
     *         {@code checkRead} method denies read access to the file.
     */
    public RecordingFile(Path file) throws IOException {
        this.file = file.toFile();
        this.input = new RecordingInput(this.file);
        findNext();
    }

    /**
     * Reads the next event in the recording.
     *
     * @return the next event, not {@code null}
     *
     * @throws EOFException if no more events exist in the recording file
     * @throws IOException if an I/O error occurs.
     *
     * @see #hasMoreEvents()
     */
    public RecordedEvent readEvent() throws IOException {
        if (eof) {
            ensureOpen();
            throw new EOFException();
        }
        isLastEventInChunk = false;
        RecordedEvent event = nextEvent;
        nextEvent = chunkParser.readEvent();
        if (nextEvent == null) {
            isLastEventInChunk = true;
            findNext();
        }
        return event;
    }

    /**
     * Returns {@code true} if unread events exist in the recording file,
     * {@code false} otherwise.
     *
     * @return {@code true} if unread events exist in the recording, {@code false}
     *         otherwise.
     */
    public boolean hasMoreEvents() {
        return !eof;
    }

    /**
     * Returns a list of all event types in this recording.
     *
     * @return a list of event types, not {@code null}
     * @throws IOException if an I/O error occurred while reading from the file
     *
     * @see #hasMoreEvents()
     */
    public List<EventType> readEventTypes() throws IOException {
        ensureOpen();
        List<EventType> types = new ArrayList<>();
        HashSet<Long> foundIds = new HashSet<>();
        try (RecordingInput ri = new RecordingInput(file)) {
            ChunkHeader ch = new ChunkHeader(ri);
            aggregateEventTypeForChunk(ch, types, foundIds);
            while (!ch.isLastChunk()) {
                ch = ch.nextHeader();
                aggregateEventTypeForChunk(ch, types, foundIds);
            }
        }
        return types;
    }

    List<Type> readTypes() throws IOException  {
        ensureOpen();
        List<Type> types = new ArrayList<>();
        HashSet<Long> foundIds = new HashSet<>();
        try (RecordingInput ri = new RecordingInput(file)) {
            ChunkHeader ch = new ChunkHeader(ri);
            aggregateTypeForChunk(ch, types, foundIds);
            while (!ch.isLastChunk()) {
                ch = ch.nextHeader();
                aggregateTypeForChunk(ch, types, foundIds);
            }
        }
        return types;
    }

    private void aggregateTypeForChunk(ChunkHeader ch, List<Type> types, HashSet<Long> foundIds) throws IOException {
        MetadataDescriptor m = ch.readMetadata();
        for (Type t : m.getTypes()) {
            if (!foundIds.contains(t.getId())) {
                types.add(t);
                foundIds.add(t.getId());
            }
        }
    }

    private static void aggregateEventTypeForChunk(ChunkHeader ch, List<EventType> types, HashSet<Long> foundIds) throws IOException {
        MetadataDescriptor m = ch.readMetadata();
        for (EventType t : m.getEventTypes()) {
            if (!foundIds.contains(t.getId())) {
                types.add(t);
                foundIds.add(t.getId());
            }
        }
    }

    /**
     * Closes this recording file and releases any system resources that are
     * associated with it.
     *
     * @throws IOException if an I/O error occurred
     */
    public void close() throws IOException {
        if (input != null) {
            eof = true;
            input.close();
            chunkParser = null;
            input = null;
            nextEvent = null;
        }
    }

    /**
     * Returns a list of all events in a file.
     * <p>
     * This method is intended for simple cases where it's convenient to read all
     * events in a single operation. It isn't intended for reading large files.
     *
     * @param path the path to the file, not {@code null}
     *
     * @return the events from the file as a {@code List} object; whether the
     *         {@code List} is modifiable or not is implementation dependent and
     *         therefore not specified, not {@code null}
     *
     * @throws IOException if an I/O error occurred, it's not a Flight Recorder
     *         file or a version of a JFR file that can't be parsed
     *
     * @throws SecurityException if a security manager exists and its
     *         {@code checkRead} method denies read access to the file.
     */
    public static List<RecordedEvent> readAllEvents(Path path) throws IOException {
        try (RecordingFile r = new RecordingFile(path)) {
            List<RecordedEvent> list = new ArrayList<>();
            while (r.hasMoreEvents()) {
                list.add(r.readEvent());
            }
            return list;
        }
    }

    // either sets next to an event or sets eof to true
    private void findNext() throws IOException {
        while (nextEvent == null) {
            if (chunkParser == null) {
                chunkParser = new ChunkParser(input);
            } else if (!chunkParser.isLastChunk()) {
                chunkParser = chunkParser.nextChunkParser();
            } else {
                eof = true;
                return;
            }
            nextEvent = chunkParser.readEvent();
        }
    }

    private void ensureOpen() throws IOException {
        if (input == null) {
            throw new IOException("Stream Closed");
        }
    }
}
