"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __values = (this && this.__values) || function(o) {
    var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
    if (m) return m.call(o);
    if (o && typeof o.length === "number") return {
        next: function () {
            if (o && i >= o.length) o = void 0;
            return { value: o && o[i++], done: !o };
        }
    };
    throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MemberHostingAndIdleTimeout = void 0;
var 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
 */
var icon_1 = require("@cocalc/frontend/components/icon");
var site_license_1 = require("@cocalc/util/consts/site-license");
var antd_1 = require("antd");
var A_1 = __importDefault(require("components/misc/A"));
var api_1 = __importDefault(require("lib/hooks/api"));
var react_1 = require("react");
var Text = antd_1.Typography.Text;
var Option = antd_1.Select.Option;
var ManagedLicenses = function (props) {
    var setConfig = props.setConfig;
    var _a = (0, api_1.default)("licenses/get-managed", undefined, 600), result = _a.result, error = _a.error, refresh = _a.call, calling = _a.calling;
    var managedLicenses = (0, react_1.useMemo)(function () {
        var _a;
        if (!Array.isArray(result))
            return [];
        var now = Date.now();
        var filtered = (_a = result === null || result === void 0 ? void 0 : result.filter(function (l) {
            var _a, _b;
            // hide expired licenses
            if (l.expires != null && l.expires < now)
                return false;
            if (((_a = l.quota) === null || _a === void 0 ? void 0 : _a.dedicated_disk) != null || ((_b = l.quota) === null || _b === void 0 ? void 0 : _b.dedicated_vm) != null) {
                return false;
            }
            return true;
        })) !== null && _a !== void 0 ? _a : [];
        filtered.sort(function (a, b) {
            var _a, _b;
            return ((_a = a.activated) !== null && _a !== void 0 ? _a : 0) - ((_b = b.activated) !== null && _b !== void 0 ? _b : 0);
        });
        return filtered;
    }, [result]);
    function shortQuotaDescription(run_limit, quota) {
        if (quota == null)
            return ""; // I saw this in production.
        var cpu = quota.cpu, ram = quota.ram, disk = quota.disk, always_running = quota.always_running, idle_timeout = quota.idle_timeout, member = quota.member;
        var up = always_running === true
            ? "always running"
            : idle_timeout != null
                ? (0, site_license_1.displaySiteLicense)(idle_timeout)
                : "idle-timeout unknown";
        var mh = member ? "member hosting" : "no member hosting";
        var res = "".concat(cpu, " CPU, ").concat(ram, "G RAM, ").concat(disk, "G disk");
        return "".concat(run_limit, "x ").concat(res, ", ").concat(up, ", ").concat(mh);
    }
    function renderLicenses() {
        if (managedLicenses == null || managedLicenses.length === 0) {
            return [
                (0, jsx_runtime_1.jsx)(Option, __assign({ value: "first", disabled: "true" }, { children: calling ? "Loading…" : "No licenses found" }), "first"),
            ];
        }
        else {
            var entries = managedLicenses.map(function (license) {
                var _a;
                // split the license id at "-" and take the last part
                var shortID = license.id.split("-").pop();
                var quota = shortQuotaDescription(license.run_limit, license.quota);
                return ((0, jsx_runtime_1.jsxs)(Option, __assign({ value: license.id }, { children: [(_a = license.title) !== null && _a !== void 0 ? _a : "No title", " ", (0, jsx_runtime_1.jsxs)(Text, __assign({ type: "secondary" }, { children: ["(", shortID, ")"] })), ": ", quota] }), license.id));
            });
            entries.unshift((0, jsx_runtime_1.jsx)(Option, __assign({ disabled: "true", value: "first" }, { children: "Select a license" }), "first"));
            return entries;
        }
    }
    function onSelection(license_id) {
        var license = managedLicenses.find(function (l) { return l.id === license_id; });
        if (license == null)
            return;
        var q = license.quota;
        if (q == null)
            return;
        var uptime = q.always_running === true ? "always_running" : q.idle_timeout;
        setConfig({ member: q.member, uptime: uptime });
    }
    if (error) {
        return ((0, jsx_runtime_1.jsx)(antd_1.Alert, { type: "error", message: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("p", { children: ["Unable to retrieve licenses:", " ", (0, jsx_runtime_1.jsx)(antd_1.Button, __assign({ type: "link", onClick: function () { return refresh(undefined, undefined, 0); } }, { children: "try again" }))] }), (0, jsx_runtime_1.jsx)("pre", __assign({ style: { whiteSpace: "pre-wrap" } }, { children: error }))] }) }));
    }
    else {
        return ((0, jsx_runtime_1.jsx)(antd_1.Select, __assign({ loading: calling, defaultValue: "first", suffixIcon: (0, jsx_runtime_1.jsx)(icon_1.Icon, { name: "reload", onClick: function () { return refresh(); } }), onChange: onSelection }, { children: renderLicenses() })));
    }
};
function MemberHostingAndIdleTimeout(props) {
    var shadowMember = props.shadowMember, setShadowMember = props.setShadowMember, form = props.form, showExplanations = props.showExplanations, onChange = props.onChange, setPresetAdjusted = props.setPresetAdjusted, _a = props.boost, boost = _a === void 0 ? false : _a, _b = props.disabled, disabled = _b === void 0 ? false : _b;
    function setConfig(_a) {
        var member = _a.member, uptime = _a.uptime;
        setUptime(uptime);
        setMemberHosting(member);
    }
    function memberExplanation() {
        if (!showExplanations)
            return;
        if (boost) {
            return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: "The state of Member Hosting must match the corresponding Site License you want to boost." }));
        }
        else {
            return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["Member hosting significantly reduces competition for resources, and we prioritize", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "support/new", external: true }, { children: "support requests" })), " ", "much higher. All licensed projects, with or without member hosting, have network access, so they can connect to the network to clone Git repositories, download data files and install software.", (0, site_license_1.requiresMemberhosting)(form.getFieldValue("uptime")) && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)(Text, __assign({ italic: true, type: "secondary" }, { children: "Note: this level of idle timeout requires member hosting." }))] })), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)(Text, __assign({ italic: true, type: "secondary" }, { children: "Please be aware: licenses of different member hosting service levels cannot be combined!" }))] }));
        }
    }
    function idleTimeoutExplanation() {
        if (!showExplanations)
            return;
        if (boost) {
            return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: "The Idle timeout of this Boost license must match the corresponding Site License you want to boost." }));
        }
        var uptime = form.getFieldValue("uptime");
        var bottom = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)(Text, __assign({ italic: true, type: "secondary" }, { children: "Please be aware: licenses with different idle timeouts cannot be combined!" }))] }));
        var main = (function () {
            if (uptime === "always_running") {
                return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Text, __assign({ strong: true, type: "secondary" }, { children: "Keep projects running:" })), " ", "Once started your project stays running, so you can run very long computations and also never have to wait for your project to start. This effectively disables", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "https://doc.cocalc.com/howto/software-development.html#idle-timeout" }, { children: "idle timeout" })), ", since your project will restart automatically if it stops. See", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "https://doc.cocalc.com/project-init.html" }, { children: "project init scripts" })), ". (Note: this is NOT guaranteed 100% uptime, since projects may sometimes restart for security and maintenance reasons.)"] }));
            }
            else {
                return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["Projects stop automatically if they are not actively used. Increasing", " ", (0, jsx_runtime_1.jsx)(A_1.default, __assign({ href: "https://doc.cocalc.com/howto/software-development.html#idle-timeout" }, { children: "idle timeout" })), " ", "will allow you to run longer calculations without you having to be active while they run. However, this is not 100% guaranteed, because projects may still restart due to maintenance or security reasons."] }));
            }
        })();
        return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [main, bottom] }));
    }
    function uptimeOptions() {
        var e_1, _a;
        var ret = [];
        try {
            for (var _b = __values(Object.entries(site_license_1.LicenseIdleTimeouts)), _c = _b.next(); !_c.done; _c = _b.next()) {
                var _d = __read(_c.value, 2), key = _d[0], it = _d[1];
                ret.push((0, jsx_runtime_1.jsx)(antd_1.Radio.Button, __assign({ value: key }, { children: it.label }), key));
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
            }
            finally { if (e_1) throw e_1.error; }
        }
        ret.push((0, jsx_runtime_1.jsx)(antd_1.Radio.Button, __assign({ value: "always_running" }, { children: "Always running" }), "always_running"));
        return ret;
    }
    function boostAssist() {
        if (!boost)
            return;
        return ((0, jsx_runtime_1.jsxs)(antd_1.Form.Item, __assign({ label: "Select license" }, { children: ["Boosts can only boost matching \"Member hosting\" and \"Idle timeout\" licenses. If you are unsure, select one of your licenses:", " ", (0, jsx_runtime_1.jsx)(ManagedLicenses, { setConfig: setConfig })] })));
    }
    function setUptime(uptime) {
        form.setFieldsValue({ uptime: uptime });
        setPresetAdjusted === null || setPresetAdjusted === void 0 ? void 0 : setPresetAdjusted(true);
        onChange();
    }
    function setMemberHosting(member) {
        form.setFieldsValue({ member: member });
        setPresetAdjusted === null || setPresetAdjusted === void 0 ? void 0 : setPresetAdjusted(true);
        onChange();
    }
    return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(antd_1.Divider, __assign({ plain: true }, { children: [boost ? "Matching" : "", " Hosting quality and Idle timeout"] })), boostAssist(), (0, jsx_runtime_1.jsx)(antd_1.Form.Item, __assign({ initialValue: true, label: "Member hosting", name: "member", valuePropName: "checked", dependencies: ["uptime"], rules: [
                    function (_a) {
                        var getFieldValue = _a.getFieldValue, setFieldsValue = _a.setFieldsValue;
                        return ({
                            validator: function (_, value) {
                                // we force member true if the uptime is higher than medium
                                var uptime = getFieldValue("uptime");
                                if ((0, site_license_1.requiresMemberhosting)(uptime)) {
                                    if (value !== true) {
                                        setShadowMember(value);
                                        setFieldsValue({ member: true });
                                    }
                                }
                                else {
                                    // if the user toggles back to a lower idle timeout,
                                    // we use shadowMember to restore the previous member value.
                                    if (shadowMember != null) {
                                        setFieldsValue({ member: shadowMember });
                                        setShadowMember(null);
                                    }
                                }
                            },
                        });
                    },
                ], extra: memberExplanation() }, { children: (0, jsx_runtime_1.jsx)(antd_1.Checkbox, __assign({ disabled: disabled || (0, site_license_1.requiresMemberhosting)(form.getFieldValue("uptime")), onChange: function (e) { return setMemberHosting(e.target.checked); } }, { children: "Run project on a much better host with network access" })) })), (0, jsx_runtime_1.jsx)(antd_1.Form.Item, __assign({ initialValue: "short", name: "uptime", label: "Idle timeout", extra: idleTimeoutExplanation() }, { children: (0, jsx_runtime_1.jsx)(antd_1.Radio.Group, __assign({ disabled: disabled, onChange: function (e) { return setUptime(e.target.value); } }, { children: uptimeOptions() })) }))] }));
}
exports.MemberHostingAndIdleTimeout = MemberHostingAndIdleTimeout;
//# sourceMappingURL=member-idletime.js.map