"use strict";
exports.id = 4012;
exports.ids = [4012];
exports.modules = {

/***/ 354012:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {


/*
 *  This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.number_of_projects_using_site_license = exports.projects_using_site_license = exports.site_license_usage_stats = exports.number_of_projects_with_license_applied = exports.number_of_running_projects_using_license = exports.numberRunningQuery = void 0;
const async_utils_1 = __webpack_require__(644181);
const misc_1 = __webpack_require__(854006);
const TIMEOUT_S = 30;
function numberRunningQuery(license_id) {
    if (!(0, misc_1.isValidUUID)(license_id)) {
        // critical to check to avoid any possible SQL injection attack.
        throw Error("invalid license_id");
    }
    // "... - 'status'" in the query, because there is always a status field (which is new)
    // an applied license not providing upgrades is just an empty object.
    return `
    SELECT COUNT(*)::INT
    FROM projects
    WHERE state ->> 'state' = 'running'
    AND ((site_license -> '${license_id}') - 'status') != '{}'::JSONB`;
}
exports.numberRunningQuery = numberRunningQuery;
async function number_of_running_projects_using_license(db, license_id) {
    /* Do a query to count the number of projects that:
        (1) are running,
        (2) have the given license_id has a key in their site_license field with a nontrivial value.
        (3) we have to ignore the "status" field, which is only information but not providing upgrades.
    */
    const query = numberRunningQuery(license_id);
    const x = await db.async_query({ query, timeout_s: TIMEOUT_S });
    return parseInt(x.rows[0].count);
}
exports.number_of_running_projects_using_license = number_of_running_projects_using_license;
async function number_of_projects_with_license_applied(db, license_id) {
    /* Do a query to count the number of projects that  have the given license_id has a key in their
       site_license field possibly with a trivial value.   Basically, this is the number of projects
       somebody has set to use this license, whether or not they have successfully actually used it.
  
    select project_id, site_license, state from projects where state#>>'{state}' in ('running', 'starting') and site_license#>>'{f3942ea1-ff3f-4d9f-937a-c5007babc693}' IS NOT NULL;
    */
    const query = `SELECT COUNT(*) FROM projects WHERE site_license#>>'{${license_id}}' IS NOT NULL`;
    const x = await db.async_query({ query, timeout_s: TIMEOUT_S });
    return parseInt(x.rows[0].count);
}
exports.number_of_projects_with_license_applied = number_of_projects_with_license_applied;
/* Returns information about how licenses are being used across ALL running projects
   in the system right now.

   The following query excludes anything with site_license null or {}, due to how sql works:

   select site_license from projects where state#>>'{state}' in ('running', 'starting') and site_license!='{}';

   We then just process the result in Javascript.  It would be possible to make a more complicated query that
   does all the processing in the database, and returns less data as output, but that would be harder for me,
   so I leave that to others or later (since this query is not likely to be used too much).
*/
async function site_license_usage_stats(db) {
    const query = "select site_license from projects where state#>>'{state}' in ('running', 'starting') and site_license!='{}'";
    const result = await db.async_query({ query });
    const usage = {};
    for (let row of result.rows) {
        for (const license_id in row.site_license) {
            if ((0, misc_1.len)(row.site_license[license_id]) > 0) {
                if (usage[license_id] == null) {
                    usage[license_id] = 1;
                }
                else {
                    usage[license_id] += 1;
                }
            }
        }
    }
    return usage;
}
exports.site_license_usage_stats = site_license_usage_stats;
function query_projects_using_site_license(license_id, cutoff) {
    const params = [];
    let query;
    if (cutoff) {
        query = `FROM projects, site_license_usage_log WHERE  `;
        query += "projects.project_id = site_license_usage_log.project_id AND ";
        query += "site_license_usage_log.license_id = $1 AND";
        query += "(site_license_usage_log.start >= $2 OR ";
        query += " site_license_usage_log.stop >= $2 OR ";
        query += " site_license_usage_log.stop IS NULL)";
        params.push(license_id);
        params.push(cutoff);
    }
    else {
        // easier -- just directly query the projects table.
        query = `
        FROM projects
        WHERE state#>>'{state}' IN ('running', 'starting')
        AND ((site_license -> '${license_id}') - 'status') != '{}'::JSONB`;
    }
    return { query, params };
}
async function projects_using_site_license(db, opts) {
    const query_fields = process_fields(opts.fields, opts.truncate);
    const { query, params } = query_projects_using_site_license(opts.license_id, opts.cutoff);
    const select = `SELECT ${query_fields.join(",")} `;
    const x = await (0, async_utils_1.callback2)(db._query.bind(db), {
        query: select + " " + query,
        limit: opts.limit,
        params,
    });
    const v = [];
    for (const row of x.rows) {
        v.push((0, misc_1.copy_with)(row, opts.fields));
    }
    return v;
}
exports.projects_using_site_license = projects_using_site_license;
function process_fields(fields, truncate) {
    const v = [];
    for (let field of fields) {
        if (truncate && (field == "title" || field == "description")) {
            field = `left(projects.${field},${truncate}) as ${field}`;
        }
        else if (field == "project_id") {
            field = `distinct(projects.project_id)`;
        }
        else {
            field = `projects.${field}`;
        }
        v.push(field);
    }
    return v;
}
async function number_of_projects_using_site_license(db, opts) {
    const { query, params } = query_projects_using_site_license(opts.license_id, opts.cutoff);
    const x = await db.async_query({
        query: "SELECT COUNT(DISTINCT(projects.project_id))::INT " + query,
        params,
        timeout_s: TIMEOUT_S,
    });
    return parseInt(x.rows[0].count);
}
exports.number_of_projects_using_site_license = number_of_projects_using_site_license;
//# sourceMappingURL=analytics.js.map

/***/ })

};
;