"use strict";
/*
 *  This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const path_to_files_1 = __importDefault(require("./path-to-files"));
const fs_1 = require("fs");
const path_1 = require("path");
const lodash_1 = require("lodash");
const file_extensions_1 = require("@cocalc/frontend/file-extensions");
const util_1 = require("./util");
const MB = 1000000;
const LIMITS = {
    listing: 10000,
    ipynb: 15 * MB,
    sagews: 10 * MB,
    other: 2 * MB,
};
async function getContents(project_id, path) {
    const fsPath = (0, path_to_files_1.default)(project_id, path);
    const obj = {};
    // use lstat instead of stat so it works on symlinks too
    const stats = await fs_1.promises.lstat(fsPath);
    obj.isdir = stats.isDirectory();
    obj.mtime = stats.mtime.valueOf();
    if (obj.isdir) {
        // get listing
        const { listing, truncated } = await getDirectoryListing(fsPath);
        obj.listing = listing;
        if (truncated) {
            obj.truncated = truncated;
        }
    }
    else {
        // get actual file content
        const ext = (0, util_1.getExtension)(fsPath);
        if ((0, file_extensions_1.hasSpecialViewer)(ext)) {
            if (stats.size >= LIMITS[ext] ?? LIMITS.other) {
                obj.truncated = "File too big to be displayed; download it instead.";
            }
            else {
                obj.content = (await fs_1.promises.readFile(fsPath)).toString();
            }
        }
        obj.size = stats.size;
    }
    return obj;
}
exports.default = getContents;
async function getDirectoryListing(path) {
    const listing = [];
    let truncated = undefined;
    for (const name of await fs_1.promises.readdir(path)) {
        if (name.startsWith(".")) {
            // We never grab hidden files.  This is a public share server after all.
            continue;
        }
        const obj = { name };
        // use lstat instead of stat so it works on symlinks too
        try {
            const stats = await fs_1.promises.lstat((0, path_1.join)(path, name));
            if (stats.isDirectory()) {
                obj.isdir = true;
                // For a directory, we define "size" to be the number of items
                // in the directory.
                obj.size = (await fs_1.promises.readdir((0, path_1.join)(path, name))).length;
            }
            else {
                obj.size = stats.size;
            }
            obj.mtime = stats.mtime.valueOf();
        }
        catch (err) {
            obj.error = err;
        }
        listing.push(obj);
        if (listing.length >= LIMITS.listing) {
            truncated = `Too many files -- only showing ${LIMITS.listing} of them.`;
            break;
        }
    }
    return { listing: (0, lodash_1.sortBy)(listing, ["name"]), truncated };
}
//# sourceMappingURL=get-contents.js.map