"use strict";
/**
 * Script parses documentation of rules, extracts meta info and add it google sheets.
 *
 * We have general rules and more specific sub rules which disclose the general rules in more detail.
 *
 * Doc structure requirements.
 *
 * Rule structure:
 * - general rule should contain at least two hashes (#)
 * - general rule should have space after hashes
 * - general rule should contain id in format number and dot after number with repeats (1.2.3.)
 * - sub rule should contain id in format cyrillic letter and dot after letter with no repeats (a.)
 * - rule should have space after id
 * - rule can contain status and rule info block:
 *      - block should starts with `\[` and ends with `\]`
 *      - block should contain one of available statuses: `Автоматизировано` | `Не автоматизировано` | `Частично автоматизировано`
 *      - if status is `Не автоматизировано` nothing else are in status and rule info block
 *      - if status is `Автоматизировано` or `Частично автоматизировано` the colon symbol (:) with space should be after status
 *      - if status is `Автоматизировано` or `Частично автоматизировано` the name of rule that automates problem should be specified
 *      - if we have several rules for automation they should be separated by comma (,) and one space
 * - rule should have space after status and rule info block if it was specified
 * - rule should have name of rule
 * - rule should have one empty line after rule row
 *
 * Examples of correct general rules:
 * - ### 1.1. \[Не автоматизировано\] Правила именования
 * - #### 2.1.2. \[Автоматизировано: brace-style\] Непустые блоки
 * - #### 2.1.4. Поля с аннтотациями
 *
 * Examples of correct sub rules:
 * - c. \[Не автоматизировано\] Между последовательно идущими объявлениями полей класса.
 * - a. \[Автоматизировано: newline-per-chained-call\] Выражение должно переноситься по точке.
 * - a. Предпочтительно размещать параметры функции на той же строке, что и имя функции.
 */
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const path = require("path");
const os = require("os");
const creds = require("./credentials/google-sheets-credentials.json");
const util_1 = require("util");
const helper_scripts_1 = require("@eigenspace/helper-scripts");
// Using require because of import issues
const GoogleSpreadsheet = require('google-spreadsheet');
// The Google Sheet ID found in the URL of your Google Sheet.
const SPREADSHEET_ID = '1phevI9VxclD8QsHYr5Stu-nlvUjJ3taBujgu1JOUqlg';
const PATH_TO_DOCS = './docs/ru/';
const FILE_NAME = 'README.md';
var StatusType;
(function (StatusType) {
    StatusType["AUTOMATED"] = "\u0410\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u043E";
    StatusType["NON_AUTOMATED"] = "\u041D\u0435 \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u043E";
    StatusType["PARTLY_AUTOMATED"] = "\u0427\u0430\u0441\u0442\u0438\u0447\u043D\u043E \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u043E";
})(StatusType || (StatusType = {}));
const ID_PATTERN = /((##[#]+ ([\d+.]+))|([a-z]\.))/.toString()
    .slice(1, -1);
const STATUS_PATTERN = Object.values(StatusType).map(statusType => `(${statusType})`)
    .join('|');
const END_PATTERN = new RegExp(`(${os.EOL}.+)*`).toString()
    .slice(1, -1);
const RULE_REGEXP = new RegExp(`${ID_PATTERN} (\\\\\\[(${STATUS_PATTERN})(.*)\\\\\\] )?(.+${END_PATTERN})`, 'gm');
const COLUMNS_COUNT = 7;
accessSpreadsheet();
function accessSpreadsheet() {
    return __awaiter(this, void 0, void 0, function* () {
        // Create a document object using the ID of the spreadsheet - obtained from its URL.
        const doc = new GoogleSpreadsheet(SPREADSHEET_ID);
        // Authenticate with the Google Spreadsheets API.
        yield util_1.promisify(doc.useServiceAccountAuth.bind(doc))(creds);
        // Get info about worksheets
        const info = yield util_1.promisify(doc.getInfo)();
        const sheets = info.worksheets;
        helper_scripts_1.walkThrough(PATH_TO_DOCS, (dir, file) => __awaiter(this, void 0, void 0, function* () {
            if (file !== FILE_NAME) {
                return;
            }
            const docType = dir.split(path.sep)
                .pop();
            const sheet = sheets.find(worksheet => worksheet.title === docType);
            if (!sheet) {
                return;
            }
            yield sheet.clear(() => {
            });
            const rules = getRulesData(path.join(dir, file));
            addRows(sheet, rules);
        }));
    });
}
function getCellsTillRow(sheet, maxRow) {
    return __awaiter(this, void 0, void 0, function* () {
        // @ts-ignore
        return util_1.promisify(sheet.getCells)({
            'min-row': 2,
            'max-row': maxRow + 1,
            'max-col': COLUMNS_COUNT,
            'min-col': 1,
            'return-empty': true
        });
    });
}
function addRows(sheet, rules) {
    return __awaiter(this, void 0, void 0, function* () {
        const cells = yield getCellsTillRow(sheet, rules.length);
        const subRuleIdRegExp = /^[a-z]/;
        let currentParentId = '';
        rules.forEach((rule, i) => {
            let { id } = rule;
            if (!subRuleIdRegExp.test(id)) {
                currentParentId = id;
            }
            else {
                id = `${currentParentId}${id}`;
            }
            const rowValues = Object.keys(rule).map(key => key === 'id' ? id : rule[key]);
            rowValues.forEach((ruleValue, j) => {
                const cellIndex = i * rowValues.length + j;
                cells[cellIndex].value = ruleValue;
            });
        });
        return sheet.bulkUpdateCells(cells);
    });
}
function getRulesData(pathToDoc) {
    const doc = fs.readFileSync(pathToDoc, 'utf8');
    const rules = doc.match(RULE_REGEXP);
    if (!rules) {
        return [];
    }
    return rules.map(rule => {
        RULE_REGEXP.lastIndex = 0;
        const [, , , ruleId, subRuleId, , status, , , , rawRuleName, name] = RULE_REGEXP.exec(rule);
        const id = ruleId || subRuleId;
        const ruleName = (rawRuleName || '').slice(1)
            .trim();
        return {
            id,
            name,
            status: status || StatusType.NON_AUTOMATED,
            rule: ruleName,
            localized: 'No',
            violations: 'None',
            link: 'link'
        };
    });
}
//# sourceMappingURL=extract-rules-meta-info-to-google-sheets.js.map