<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Memory Monitor</title>

    <!-- Add MaterializeCSS -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

    <!-- Custom CSS -->
    <style>
        body {
            font-family: 'Roboto', sans-serif;
            background-color: #f5f5f5;
            display: flex;
            flex-direction: column;
            min-height: 100vh;
        }

        h1, h3, h5 {
            font-weight: 300;
        }

        .container {
            width: 90%;
            max-width: 100%;
            min-width: 500px;
            flex-grow: 1;
        }

        .card {
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            transition: 0.3s;
            width: 100%;
        }

        .card-content {
            padding: 20px;
            line-break: anywhere;
            word-wrap: normal;
            overflow: auto;
        }

        .card-title {
            font-size: 1.5rem;
            font-weight: 300;
        }

        #clock {
            text-align: center;
            position: absolute;
            top: 0;
            right: 5%;
            background: #333;
            color: #eee;
            border-radius: 5px;
            border: 1px solid #000;
            padding: 3px;
            z-index: 5000;
        }

        #memory-chart {
            width: 100%;
            margin: 0 auto;
        }

        .card:hover {
            transform: translateY(-5px);
            background: #333;
            color: #eee;
        }

        .spinner {
            display: inline-block;
            width: 20px;
            height: 20px;
            border: 2px solid rgba(0, 0, 0, .1);
            border-left-color: #333;
            border-radius: 50%;
            animation: spin 1s linear infinite;
        }

        @keyframes spin {
            to {
                transform: rotate(360deg);
            }
        }

        .row {
            display: flex;
            flex-wrap: wrap;
            justify-content: space-around;
        }

        .card-wrapper {
            flex: 1;
            display: flex;
            min-width: 280px;
            max-width: 400px;
        }

        .col {
            display: flex;
        }
    </style>
</head>

<body>
    <div class="container">
        <h1 class="center-align">Memory Monitor</h1>
        <div class="row">
            <div class="col s12">
                <h5 class="center-align" id="clock">...</h5>
            </div>
        </div>
        <div class="row">
            <div class="col s12 m6 l4 card-wrapper">
                <div class="card">
                    <div class="card-content">
                        <span class="card-title">Django Memory Usage</span>
                        <h3 class="center-align" id="django-memory-usage"><span class="spinner"></span></h3>
                    </div>
                </div>
            </div>
            <div class="col s12 m6 l4 card-wrapper">
                <div class="card">
                    <div class="card-content">
                        <span class="card-title">Celery Memory Usage</span>
                        <h3 class="center-align" id="celery-memory-usage"><span class="spinner"></span></h3>
                    </div>
                </div>
            </div>
            <div class="col s12 m6 l4 card-wrapper">
                <div class="card">
                    <div class="card-content">
                        <span class="card-title">CPU Usage</span>
                        <h3 class="center-align" id="cpu-usage"><span class="spinner"></span></h3>
                    </div>
                </div>
            </div>
            <div class="col s12 m6 l4 card-wrapper">
                <div class="card">
                    <div class="card-content">
                        <span class="card-title">Total System Memory</span>
                        <h3 class="center-align" id="total-system-memory"><span class="spinner"></span></h3>
                    </div>
                </div>
            </div>
            <div class="col s12 m6 l4 card-wrapper">
                <div class="card">
                    <div class="card-content">
                        <span class="card-title">Available Memory</span>
                        <h3 class="center-align" id="available-memory"><span class="spinner"></span></h3>
                    </div>
                </div>
            </div>
            <div class="col s12 m6 l4 card-wrapper">
                <div class="card">
                    <div class="card-content">
                        <span class="card-title">Virtual Memory %</span>
                        <h3 class="center-align" id="memory-percent"><span class="spinner"></span></h3>
                    </div>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col s12 m6 14">
                <div class="card">
                    <div class="card-content">
                        <span class="card-title">Top Memory Processes</span>
                        <div class="processes">
                            <ol id="processes-list">
                                <li><span class="spinner"></span></li>
                            </ol>
                        </div>
                    </div>
                </div>
            </div>
            <div class="col s12 m6 14">
                <div class="card">
                    <div class="card-content">
                        <span class="card-title">Celery Workers</span>
                        <div class="celery-workers">
                            <ol id="celery-workers-list">
                                <li><span class="spinner"></span></li>
                            </ol>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col s12 m6 14">
                <div class="card">
                    <div class="card-content">
                        <span class="card-title">Top Memory-consuming Django Views/Functions</span>
                        <div class="top-views">
                            <ol id="top-views-list">
                                <li><span class="spinner"></span></li>
                            </ol>
                        </div>
                    </div>
                </div>
            </div>
            <div class="col s12 m6 14">
                <div class="card">
                    <div class="card-content">
                        <span class="card-title">Python Processes Memory Usage</span>
                        <div class="python-processes">
                            <ol id="python-processes-list">
                                <li>...</li>
                            </ol>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <div class="row">
            <div class="col s12 m6 14" style="width: 100%;">
                <div class="card-content" style="width: 100%;">
                    <span class="card-title">Memory Usage Chart</span>
                    <div style="width: 100%;">
                        <canvas id="memory-chart"></canvas>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        $(document).ready(function() {
            updateMemoryUsage();

            function updateClock() {
                const now = new Date();
                const hours = now.getHours().toString().padStart(2, '0');
                const minutes = now.getMinutes().toString().padStart(2, '0');
                const seconds = now.getSeconds().toString().padStart(2, '0');
                $("#clock").text(hours + ':' +
                minutes + ':' + seconds);
            }

            // Update the clock every second (1000 milliseconds)
            setInterval(updateClock, 1000);

            // Create memory usage chart
            const ctx = document.getElementById('memory-chart').getContext('2d');
            const memoryChartData = {
                labels: [],
                datasets: [{
                    label: 'Memory Usage',
                    data: [],
                    borderColor: 'rgb(75, 192, 192)',
                    tension: 0.1,
                }]
            };
            const memoryChart = new Chart(ctx, {
                type: 'line',
                data: memoryChartData,
                options: {
                    scales: {
                        x: {
                            display: true,
                            title: {
                                display: true,
                                text: 'Time'
                            }
                        },
                        y: {
                            display: true,
                            title: {
                                display: true,
                                text: 'Memory Usage (MB)'
                            }
                        }
                    }
                }
            });

            function updateMemoryUsage() {
                $.ajax({
                    url: '/core/memory-monitor/memory-usage/',
                    success: function(data) {
                        $("#django-memory-usage").html(data.memory_usage + ' MB');
                        $("#celery-memory-usage").html(data.celery + ' MB');
                        $("#cpu-usage").html(data.cpu_usage + ' %');
                        $("#total-system-memory").html(data.total_system_memory + ' MB');
                        $('#processes-list').empty();
                        for (process of data.processes) {
                            $('#processes-list').append(
                                '<li>' + process.name + ' - ' + process.memory + ' MB</li>'
                            );
                        }
                        // Update available memory
                        $("#available-memory").html(data.available_memory + ' MB');
                        $("#memory-percent").html(data.memory_percent + ' %');

                        // Update the memory usage for each Celery thread
                        /**
                        let threadList = "";
                        for (const thread of data.celery_tasks) {
                            threadList += thread + ' MB, ';
                        }
                        threadList = threadList.slice(0, -2);
                        $("#celery-memory-usage").html(threadList);
                        */

                        $('#top-views-list').empty();
                        for (view of data.top_views) {
                            $('#top-views-list').append(
                                '<li>' + view.filename + ':' + view.lineno + ' - ' + view.size + ' MB</li>'
                            );
                        }

                        // Update memory usage for each Celery worker and task
                        $('#celery-workers-list').empty();
                        for (worker of data.celery_workers) {
                            $('#celery-workers-list').append(
                                '<li>' + worker.name + ' - ' + worker.memory + ' MB</li>'
                            );
                        }

                        // Update memory usage for Python processes
                        $('#python-processes-list').empty();
                        for (process of data.python_processes) {
                            $('#python-processes-list').append(
                                '<li>' + process.name + ' - ' + process.memory + ' MB</li>'
                            );
                        }

                        // Update memory chart
                        memoryChartData.labels.push(new Date().toLocaleTimeString());
                        memoryChartData.datasets[0].data.push(data.memory_usage);
                        if (memoryChartData.labels.length > 50) {
                            memoryChartData.labels.shift();
                            memoryChartData.datasets[0].data.shift();
                        }
                        memoryChart.update();
                    }
                });
            }

            // Update memory usage every 3 seconds (3000 milliseconds)
            setInterval(updateMemoryUsage, 3000);
        });
    </script>
</body>
</html>
