"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.QuotaConfig = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
/*
 *  This file is part of CoCalc: Copyright © 2022 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */
const icon_1 = require("@cocalc/frontend/components/icon");
const site_license_1 = require("@cocalc/util/consts/site-license");
const misc_1 = require("@cocalc/util/misc");
const consts_1 = require("@cocalc/util/upgrades/consts");
const antd_1 = require("antd");
const A_1 = __importDefault(require("components/misc/A"));
const integer_slider_1 = __importDefault(require("components/misc/integer-slider"));
const quota_config_presets_1 = require("./quota-config-presets");
const { Text } = antd_1.Typography;
const { TabPane } = antd_1.Tabs;
const EXPERT_CONFIG = "Expert configuration";
const QuotaConfig = (props) => {
    const { showExplanations, form, disabled = false, onChange, boost = false, configMode, setConfigMode, preset, setPreset, presetAdjusted, setPresetAdjusted, } = props;
    function title() {
        if (boost) {
            return "Booster";
        }
        else {
            return "Quota upgrades";
        }
    }
    const PARAMS = boost ? consts_1.BOOST : consts_1.REGULAR;
    function explainRam() {
        if (!showExplanations)
            return;
        return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["This quota limits the total amount of memory a project can use. Note that RAM may be limited, if many other users are using the same host \u2013 though member hosting significantly reduces competition for RAM. We recommend at least 2G! Beyond the overall maximum of ", consts_1.MAX_RAM_GB, "G, we also offer", " ", (0, jsx_runtime_1.jsx)(A_1.default, { href: "/store/dedicated?type=vm", children: "dedicated virtual machines" }), " with larger memory options."] }));
    }
    /**
     * When a quota is changed, we warn the user that the preset was adjusted. (the text updates, though, since it rerenders every time). Explanation in the details could make no sense, though – that's why this is added.
     */
    function presetWasAdjusted() {
        setPresetAdjusted?.(true);
    }
    function ram() {
        return ((0, jsx_runtime_1.jsx)(antd_1.Form.Item, { label: "Shared RAM", name: "ram", initialValue: PARAMS.ram.dflt, extra: explainRam(), children: (0, jsx_runtime_1.jsx)(integer_slider_1.default, { disabled: disabled, min: PARAMS.ram.min, max: PARAMS.ram.max, onChange: (ram) => {
                    form.setFieldsValue({ ram });
                    presetWasAdjusted();
                    onChange();
                }, units: "G RAM", presets: boost ? [0, 2, 4, 8, 10] : [1, 2, 4, 8, 16] }) }));
    }
    function cpu() {
        return ((0, jsx_runtime_1.jsx)(antd_1.Form.Item, { label: "Shared CPUs", name: "cpu", initialValue: PARAMS.cpu.dflt, extra: showExplanations ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(A_1.default, { href: "https://cloud.google.com/compute/docs/faq#virtualcpu", children: "Google cloud vCPU's." }), " ", "To keep prices low, these vCPU's may be shared with other projects, though member hosting very significantly reduces competition for CPUs. We also offer", " ", (0, jsx_runtime_1.jsx)(A_1.default, { href: "/store/dedicated?type=vm", children: "dedicated virtual machines" }), " ", "with more CPU options."] })) : undefined, children: (0, jsx_runtime_1.jsx)(integer_slider_1.default, { disabled: disabled, min: PARAMS.cpu.min, max: PARAMS.cpu.max, onChange: (cpu) => {
                    form.setFieldsValue({ cpu });
                    presetWasAdjusted();
                    onChange();
                }, units: "vCPU", presets: boost ? [0, 1, 2] : [1, 2, 3] }) }));
    }
    function disk() {
        // 2022-06: price increase "version 2": minimum disk we sell (also the free quota) is 3gb, not 1gb
        return ((0, jsx_runtime_1.jsx)(antd_1.Form.Item, { label: "Disk space", name: "disk", initialValue: PARAMS.disk.dflt, extra: showExplanations ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["Extra disk space lets you store a larger number of files. Snapshots and file edit history is included at no additional charge. Each project receives at least ", consts_1.DISK_DEFAULT_GB, "G of storage space. We also offer much larger", " ", (0, jsx_runtime_1.jsx)(A_1.default, { href: "/store/dedicated?type=disk", children: "dedicated disks" }), "."] })) : undefined, children: (0, jsx_runtime_1.jsx)(integer_slider_1.default, { disabled: disabled, min: PARAMS.disk.min, max: PARAMS.disk.max, onChange: (disk) => {
                    form.setFieldsValue({ disk });
                    presetWasAdjusted();
                    onChange();
                }, units: "G Disk", presets: boost ? [0, 3, 6, PARAMS.disk.max] : [3, 5, 10, PARAMS.disk.max] }) }));
    }
    function infoText() {
        if (preset == null) {
            return ((0, jsx_runtime_1.jsx)(Text, { type: "danger", children: "Currently, no preset selection is active. Select a preset above to reset your recent changes." }));
        }
        const cpuValue = form.getFieldValue("cpu");
        const ramValue = form.getFieldValue("ram");
        const diskValue = form.getFieldValue("disk");
        const memberValue = form.getFieldValue("member");
        const uptimeValue = form.getFieldValue("uptime");
        if (cpuValue == null ||
            ramValue == null ||
            diskValue == null ||
            memberValue == null ||
            uptimeValue == null)
            return;
        const presetData = quota_config_presets_1.PRESETS[preset];
        if (presetData == null) {
            return ((0, jsx_runtime_1.jsxs)("div", { children: ["Error: preset ", (0, jsx_runtime_1.jsx)("code", { children: preset }), " is not known."] }));
        }
        const { name, descr, details } = presetData;
        function presetDescription() {
            if (!descr) {
                return "";
            }
            else {
                return (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [descr, ". It"] });
            }
        }
        function renderDetails() {
            if (details) {
                return details;
            }
        }
        function renderProvides() {
            const basic = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["provides up to", " ", (0, jsx_runtime_1.jsxs)(Text, { strong: true, children: [cpuValue, " CPU ", (0, misc_1.plural)(cpuValue, "core")] }), ", ", (0, jsx_runtime_1.jsxs)(Text, { strong: true, children: [ramValue, "G memory"] }), ", and", " ", (0, jsx_runtime_1.jsxs)(Text, { strong: true, children: [diskValue, "G disk space"] }), " for each project."] }));
            const mh = memberValue === false ? ((0, jsx_runtime_1.jsx)(Text, { strong: true, children: "member hosting is disabled" })) : null;
            const ut = uptimeValue !== "short" ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [mh != null ? " and" : "", " the project's", " ", (0, jsx_runtime_1.jsxs)(Text, { strong: true, children: ["idle timeout is ", (0, site_license_1.displaySiteLicense)(uptimeValue)] })] })) : null;
            const any = mh != null || ut != null;
            return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [basic, " ", any ? "Additionally, " : "", mh, ut, any ? "." : ""] }));
        }
        function presetIsAdjusted() {
            if (!presetAdjusted)
                return;
            return ((0, jsx_runtime_1.jsx)(antd_1.Typography, { style: { marginBottom: "10px" }, children: (0, jsx_runtime_1.jsx)(Text, { type: "warning", children: "The preset has been adjusted and parts of the description might no longer be applicable. If you select another one, your modifications will be reset." }) }));
        }
        return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [presetIsAdjusted(), (0, jsx_runtime_1.jsxs)(antd_1.Typography, { children: ["Preset ", (0, jsx_runtime_1.jsxs)(Text, { strong: true, children: ["\"", name, "\""] }), " ", presetDescription(), " ", renderProvides(), " ", renderDetails()] })] }));
    }
    function presetsCommon() {
        if (!showExplanations)
            return null;
        return ((0, jsx_runtime_1.jsxs)(Text, { type: "secondary", children: ["After selecting a preset, feel free to fine tune the selection in the \"", EXPERT_CONFIG, "\" or change the \"Member hosting\" or the \"Idle timeout\" configuration below. Subsequent preset selections will reset your adjustments."] }));
    }
    function presetExtra() {
        return ((0, jsx_runtime_1.jsxs)(antd_1.Space, { direction: "vertical", children: [(0, jsx_runtime_1.jsx)("div", {}), (0, jsx_runtime_1.jsx)("div", { children: infoText() }), presetsCommon()] }));
    }
    function onPresetChange(newVal) {
        const val = newVal.target.value;
        if (val == null || setPreset == null)
            return;
        setPreset(val);
        setPresetAdjusted?.(false);
        const preset = quota_config_presets_1.PRESETS[val];
        if (preset != null) {
            const { cpu, ram, disk, uptime = "short", member = true } = preset;
            form.setFieldsValue({ uptime, member, cpu, ram, disk });
        }
        onChange();
    }
    function presets() {
        return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(antd_1.Form.Item, { label: "Presets", shouldUpdate: true, extra: presetExtra(), children: (0, jsx_runtime_1.jsx)(antd_1.Radio.Group, { onChange: onPresetChange, value: preset, children: (0, jsx_runtime_1.jsx)(antd_1.Space, { size: [10, 10], wrap: true, children: Object.keys(quota_config_presets_1.PRESETS).map((p) => {
                            const presetData = quota_config_presets_1.PRESETS[p];
                            return ((0, jsx_runtime_1.jsxs)(antd_1.Radio.Button, { value: p, children: [(0, jsx_runtime_1.jsx)(icon_1.Icon, { name: presetData.icon ?? "arrow-up" }), " ", presetData.name] }, p));
                        }) }) }) }) }));
    }
    function detailed() {
        return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [ram(), cpu(), disk()] }));
    }
    function main() {
        if (boost) {
            return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(antd_1.Row, { children: (0, jsx_runtime_1.jsx)(antd_1.Col, { xs: 16, offset: 6, style: { marginBottom: "20px" }, children: (0, jsx_runtime_1.jsx)(Text, { type: "secondary", children: "Configure the quotas you want to add on top of your existing license. E.g. if your license provides a limit of 2G of RAM and you add a matching boost license with 3G of RAM, you'll end up with a total quota limit of 5G of RAM." }) }) }), detailed()] }));
        }
        else {
            return ((0, jsx_runtime_1.jsxs)(antd_1.Tabs, { activeKey: configMode, onChange: setConfigMode, type: "card", tabPosition: "top", size: "middle", centered: true, children: [(0, jsx_runtime_1.jsx)(TabPane, { tab: (0, jsx_runtime_1.jsxs)("span", { children: [(0, jsx_runtime_1.jsx)(icon_1.Icon, { name: "lightbulb" }), "Quota presets"] }), children: presets() }, "preset"), (0, jsx_runtime_1.jsx)(TabPane, { tab: (0, jsx_runtime_1.jsxs)("span", { children: [(0, jsx_runtime_1.jsx)(icon_1.Icon, { name: "wrench" }), EXPERT_CONFIG] }), children: detailed() }, "expert")] }));
        }
    }
    return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(antd_1.Divider, { plain: true, children: title() }), main()] }));
};
exports.QuotaConfig = QuotaConfig;
//# sourceMappingURL=quota-config.js.map