<?php

$_SERVER['DOCUMENT_ROOT'] = "..";

$app = json_decode(file_get_contents("./app.json"), true);
$start = microtime(true);
@mkdir("./data");
@mkdir("./data/backup");

$files = [];
$restored = [];
$times = [];

$currentOpStart = microtime(true);
file_put_contents("./data/actions/" . date('Y-m-d_H-i-s') . ".json", @file_get_contents("./data/actions/actions.json"));
file_put_contents("./data/toys/" . date('Y-m-d_H-i-s') . ".json", @file_get_contents("./data/toys/toys.json"));

exec('bash -c "cd /nas/web/ponies.equestria.horse/includes/data; ls -tp toys/20* | grep -v \'/$\' | tail -n +20 | xargs -I {} rm -- {}"');
exec('bash -c "cd /nas/web/ponies.equestria.horse/includes/data; ls -tp actions/20* | grep -v \'/$\' | tail -n +20 | xargs -I {} rm -- {}"');

$times["important_backup"] = microtime(true) - $currentOpStart;

$currentOpStart = microtime(true);
$documents = array_map(function ($i) {
    return [
        "id" => substr($i, 0, -5),
        ...(json_decode(file_get_contents("./data/docs/" . $i), true) ?? [])
    ];
}, array_filter(scandir("./data/docs"), function ($i) {
    return !str_starts_with($i, ".") && str_ends_with($i, ".json");
}));

$deletable = array_values(array_filter($documents, function ($i) {
    return str_starts_with(strip_tags($i["contents"]), "/delete");
}));

foreach ($deletable as $item) {
    if (time() - $item["last"]["date"] > 86400) {
        unlink("./data/docs/" . $item["id"] . ".json");
    }
}
$times["docs_cleanup"] = microtime(true) - $currentOpStart;

require_once "./cleanup.inc";

$currentOpStart = microtime(true);
$version = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/version.json"), true);

$ignore = [
    $_SERVER['DOCUMENT_ROOT'] . "/Data",
    $_SERVER['DOCUMENT_ROOT'] . "/bits/Data",
    $_SERVER['DOCUMENT_ROOT'] . "/Private/Data",
    $_SERVER['DOCUMENT_ROOT'] . "/bits/Data",
    $_SERVER['DOCUMENT_ROOT'] . "/bits/Private/Data",
    $_SERVER['DOCUMENT_ROOT'] . "/includes/data",
    $_SERVER['DOCUMENT_ROOT'] . "/includes/tokens",
    $_SERVER['DOCUMENT_ROOT'] . "/app",
    $_SERVER['DOCUMENT_ROOT'] . "/assets",
];

function rscandir($dir) {
    global $ignore;
    $files = [];

    foreach (array_filter(scandir($dir), function ($i) {
        return !str_starts_with($i, ".");
    }) as $file) {
        if (in_array($dir . "/" . $file, $ignore)) continue;

        if (is_dir($dir . "/" . $file)) {
            array_push($files, ...rscandir($dir . "/" . $file));
        } else {
            $files[] = $dir . "/" . $file;
        }
    }

    return array_unique($files);
}

function calculateVersionNumber() {
    $files = rscandir($_SERVER['DOCUMENT_ROOT']);
    $hashes = [];

    foreach ($files as $file) {
        $hashes[] = md5_file($file);
    }

    $hash = md5(implode("", $hashes));
    return [$hash, $hashes];
}

$versionHash = calculateVersionNumber();

if ($versionHash[0] !== $version["hash"]) {
    $version["hash"] = $versionHash[0];
    $version["timestamp"] = time();
    $version["revision"] = 0;
    $version["list"] = [
        "current" => $versionHash[1],
        "old" => isset($version["list"]) ? $version["list"]["current"] ?? null : null
    ];
    $version["build"]++;
} else {
    $version["revision"]++;
}

file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/version.json", json_encode($version));
$times["version"] = microtime(true) - $currentOpStart;

$currentOpStart = microtime(true);
foreach (array_filter(scandir("./data"), function ($i) {
    return !str_starts_with($i, ".") && $i !== "backup" && (is_file("./data/" . $i) || is_dir("./data/" . $i));
}) as $file) {
    if (is_dir("./data/" . $file)) {
        foreach (array_filter(scandir("./data"), function ($i) use ($file) {
            return !str_starts_with($i, ".") && $i !== "backup" && is_file("./data/" . $file . "/" . $i);
        }) as $file2) {
            @mkdir("./data/backup/" . $file);
            $files[] = $file . "/" . $file2;
        }
    } else {
        $files[] = $file;
    }
}

@mkdir("./data/backup");
foreach ($files as $file) {
    copy("./data/" . $file, "./data/backup/" . $file);
}

function getSystem(string $id) {
    global $times;
    echo("System: $id\n");

    echo("    Base system info\n");
    $currentOpStart = microtime(true);
    $data = file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id");

    if (trim($data) !== "" && $data !== false) {
        file_put_contents("./data/$id/general.json", $data);
    }
    $times["system-general-$id"] = microtime(true) - $currentOpStart;

    echo("    System members\n");
    $currentOpStart = microtime(true);
    $data = file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id/members");

    if (trim($data) !== "" && $data !== false) {
        file_put_contents("./data/$id/members.json", $data);
    }
    $times["system-members-$id"] = microtime(true) - $currentOpStart;

    echo("    Fronters\n");
    $data = file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id/fronters");

    if (trim($data) !== "" && $data !== false) {
        file_put_contents("./data/$id/fronters.json", $data);
    }
    $times["system-fronters-$id"] = microtime(true) - $currentOpStart;

    echo("    Switches\n");
    $currentOpStart = microtime(true);

    echo("        Part 1/3\n");
    $switches1 = json_decode(file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id/switches"), true);
    $oldest = $switches1[count($switches1) - 1]["timestamp"];

    echo("        Part 2/3\n");
    $switches2 = json_decode(file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id/switches?before=$oldest"), true);
    $oldest = $switches2[count($switches2) - 1]["timestamp"];

    echo("        Part 3/3\n");
    $switches3 = json_decode(file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id/switches?before=$oldest"), true);

    if ($switches1 !== null && $switches2 !== null && $switches3 !== null) {
        file_put_contents("./data/$id/switches.json", json_encode([...$switches1, ...$switches2, ...$switches3], JSON_PRETTY_PRINT));
        $times["system-switches-$id"] = microtime(true) - $currentOpStart;
    }
}

getSystem("gdapd"); // Raindrops
getSystem("ynmuc"); // Cloudburst

echo("Calendar\n");
$currentOpStart = microtime(true);
file_put_contents("./data/calendar/calendar.ics", file_get_contents($app["calendar"]));
$times["calendar"] = microtime(true) - $currentOpStart;

echo("Downloading images.\n");
if (!file_exists("./data/images")) mkdir("./data/images");

foreach (json_decode(file_get_contents("./data/gdapd/members.json"), true) as $member) {
    $currentOpStart2 = microtime(true);
    echo("    " . $member['id'] . "\n");

    if (isset($member['avatar_url'])) {
        echo("        Profile picture\n");
        file_put_contents("/tmp/img." . pathinfo($member['avatar_url'], PATHINFO_EXTENSION), file_get_contents($member['avatar_url']));
        exec("convert -resize 128x128 -quality 50 \"" . "/tmp/img." . pathinfo($member['avatar_url'], PATHINFO_EXTENSION) . "\" \"./data/images/pf-gdapd-" . $member['id'] . ".webp\"");
        unlink("/tmp/img." . pathinfo($member['avatar_url'], PATHINFO_EXTENSION));
    }

    echo("        Pony Town character\n");
    if (file_exists("../assets/uploads/pt-" . $member['name'] . ".png")) {
        exec("convert -resize 64x64 -quality 50 \"../assets/uploads/pt-" . $member['name'] . ".png\" \"./data/images/pt-gdapd-" . $member['id'] . ".png\"");
    } else {
        exec("convert -resize 64x64 -quality 50 \"../assets/uploads/pt.png\" \"./data/images/pt-gdapd-" . $member['id'] . ".png\"");
    }
    $times["images-gdapd-" . $member['id']] = microtime(true) - $currentOpStart2;
}

foreach (json_decode(file_get_contents("./data/ynmuc/members.json"), true) as $member) {
    $currentOpStart2 = microtime(true);
    echo("    " . $member['id'] . "\n");

    if (isset($member['avatar_url'])) {
        echo("        Profile picture\n");
        file_put_contents("/tmp/img." . pathinfo($member['avatar_url'], PATHINFO_EXTENSION), file_get_contents($member['avatar_url']));
        exec("convert -resize 128x128 -quality 50 \"" . "/tmp/img." . pathinfo($member['avatar_url'], PATHINFO_EXTENSION) . "\" \"./data/images/pf-ynmuc-" . $member['id'] . ".webp\"");
        unlink("/tmp/img." . pathinfo($member['avatar_url'], PATHINFO_EXTENSION));
    }

    echo("        Pony Town character\n");
    if (file_exists("../assets/uploads/pt-" . $member['name'] . ".png")) {
        exec("convert -resize 64x64 -quality 50 \"../assets/uploads/pt-" . $member['name'] . ".png\" \"./data/images/pt-ynmuc-" . $member['id'] . ".png\"");
    } else {
        exec("convert -resize 64x64 -quality 50 \"../assets/uploads/pt.png\" \"./data/images/pt-ynmuc-" . $member['id'] . ".png\"");
    }
    $times["images-ynmuc-" . $member['id']] = microtime(true) - $currentOpStart2;
}

echo("Backing up...\n");

if (date('i') === "00") {
    require_once "./backup.inc";
    echo("Backup completed\n");
} else {
    echo("Backup skipped\n");
}

echo("Generating logo...\n");

$currentOpStart = microtime(true);
require_once "./logo.inc";
$times["logo"] = microtime(true) - $currentOpStart;

echo("Generated logo\n");

echo("Generating favicons...\n");

$currentOpStart = microtime(true);
require_once "./icons.inc";
$times["favicons"] = microtime(true) - $currentOpStart;

echo("Generated favicons\n");

echo("Downloading assets...\n");

$currentOpStart = microtime(true);
require_once "./assets.inc";
$times["assets"] = microtime(true) - $currentOpStart;

echo("Downloading assets\n");

$time = array_sum($times);
echo("Completed in " . $time . " seconds.\n");

file_put_contents("./data/refresh.json", json_encode([
    "timestamp" => microtime(true),
    "duration" => $time,
    "restored" => $restored,
    "times" => $times
]));