/* global use, db */
// MongoDB Playground
// To disable this template go to Settings | MongoDB | Use Default Template For Playground.
// Make sure you are connected to enable completions and to be able to run a playground.
// Use Ctrl+Space inside a snippet or a string literal to trigger completions.
// The result of the last command run in a playground is shown on the results panel.
// By default the first 20 documents will be returned with a cursor.
// Use 'console.log()' to print to the debug output.
// For more documentation on playgrounds please refer to
// https://www.mongodb.com/docs/mongodb-vscode/playgrounds/
use("statistics");

let formattedDate = (date) => ({
    unix: { $toLong: date },
    iso: { $toString: date },
});

db.getCollection("peertube_ts").aggregate([
    {
        $sort: { timestamp: 1 }
    },
    {
        $group: {
            _id: "$tags.session",
            host: { $first: "$tags.host" },
            firstTimestamp: { $first: "$timestamp" },
            lastTimestamp: { $last: "$timestamp" },
            firstTimestampWithPeers: {
                $min: {
                    $cond: {
                        if: { $gt: [{ $size: { $ifNull: ["$peers", []] } }, 0] },
                        then: "$timestamp",
                        else: null,
                    }
                }
            },
            maxNumberOfPeers: {
                $max: {
                    $size: { $ifNull: ["$peers", []] },
                }
            },
            minNumberOfPeers: {
                $min: {
                    $size: { $ifNull: ["$peers", []] },
                }
            }
        }
    },
    // Lookup other sessions that may have peers
    {
        $lookup: {
            from: "peertube_ts",
            let: { currentSession: "$_id", ftp: "$firstTimestampWithPeers", fst: "$firstTimestamp" },
            pipeline: [
                {
                    $match: {
                        $expr: {
                            $and: [
                                { $ne: ["$tags.session", "$$currentSession"] },
                                { $lt: ["$timestamp", "$$ftp"] },
                                { $gte: ["$timestamp", "$$fst"] },
                                { $gt: [{ $size: { $ifNull: ["$peers", []] } }, 0] }
                            ]
                        }
                    }
                }
            ],
            as: "concurrentSessions"
        }
    },
    // Mark whether peers existed in other sessions before starting
    {
        $addFields: {
            concurrentSessions: {
                $gt: [{ $size: "$concurrentSessions" }, 0]
            }
        }
    },
    {
        $group: {
            _id: "$host",
            sessions: {
                $push: {
                    id: "$_id",
                    startTime: formattedDate("$firstTimestamp"),
                    endTime: formattedDate("$lastTimestamp"),
                    duration: {
                        $divide: [
                            {
                                $subtract: ["$lastTimestamp", "$firstTimestamp"],
                            },
                            1000,
                        ]
                    },
                    firstPeerConnection: {
                        $cond: {
                            if: { $eq: ["$firstTimestampWithPeers", null] },
                            then: null,
                            else: {
                                time: {
                                    date: formattedDate("$firstTimestampWithPeers"),
                                    elapsedFromStart: {
                                        $divide: [
                                            {
                                                $subtract: ["$firstTimestampWithPeers", "$firstTimestamp"],
                                            },
                                            1000,
                                        ]
                                    }
                                },
                                concurrentSessions: "$concurrentSessions",
                            }
                        }
                    },
                    maxPeers: { $max: "$maxNumberOfPeers" },
                    minPeers: { $min: "$minNumberOfPeers" }
                }
            }
        }
    },
    { 
        $set: {
            sessions: {
                $sortArray: {
                    input: "$sessions",
                    sortBy: { id: 1 }
                }
            }
        }
    },
    {
        $project: {
            _id: 0,
            host: "$_id",
            sessions: "$sessions"
        }
    },
    {
        $sort: { host: 1 }
    }
]);
