/*******************************************************************************

    uBlock Origin Lite - a comprehensive, MV3-compliant content blocker
    Copyright (C) 2014-present Raymond Hill

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see {http://www.gnu.org/licenses/}.

    Home: https://github.com/gorhill/uBlock
*/

import { runtime, sendMessage } from './ext.js';
import { DNREditor } from './dnr-editor.js';
import { i18n$ } from './i18n.js';
import { normalizeDNRRules } from './ext-compat.js';
import { textFromRules } from './dnr-parser.js';

/******************************************************************************/

export class ReadOnlyDNREditor extends DNREditor {
    async getText(hint) {
        if ( hint === 'dnr.ro.dynamic' ) {
            const rules = await sendMessage({ what: 'getAllDynamicRules' });
            if ( Array.isArray(rules) === false ) { return; }
            this.id = 'dynamic';
            this.count = rules.length;
            return textFromRules(rules, { keepId: true });
        }
        if ( hint === 'dnr.ro.session' ) {
            const rules = await sendMessage({ what: 'getAllSessionRules' });
            if ( Array.isArray(rules) === false ) { return; }
            this.id = 'session';
            this.count = rules.length;
            return textFromRules(rules, { keepId: true });
        }
        const match = /^dnr\.ro\.(.+)$/.exec(hint);
        if ( match === null ) { return; }
        this.id = match[1];
        const allRulesetDetails = await sendMessage({ what: 'getRulesetDetails' });
        const rulesetDetails = allRulesetDetails.find(a => a.id === this.id);
        if ( rulesetDetails === undefined ) { return; }
        const manifestRulesets = runtime.getManifest().declarative_net_request.rule_resources;
        const mainPathMap = new Map(
            manifestRulesets.map(({ id, path }) => [ id, path ])
        );
        const realms = {
            plain: 'main',
            regex: 'regex',
        };
        const promises = [];
        for ( const [ realm, dir ] of Object.entries(realms) ) {
            if ( Boolean(rulesetDetails.rules?.[realm]) === false ) { continue; }
            const url = dir === 'main'
                ? mainPathMap.get(this.id)
                : `./rulesets/${dir}/${this.id}.json`;
            promises.push(
                fetch(url).then(response =>
                    response.json()
                ).then(rules =>
                    normalizeDNRRules(rules)
                )
            );
        }
        const parts = await Promise.all(promises);
        const allRules = [];
        for ( const rules of parts ) {
            for ( const rule of rules ) {
                allRules.push(rule);
            }
        }
        this.count = allRules.length;
        return textFromRules(allRules, { keepId: true });
    }

    on(editor) {
        if ( typeof this.count !== 'number' ) {
            return editor.updateSummaryPanel(null);
        }
        const template = document.querySelector('template.ro-summary-panel');
        const fragment = template.content.cloneNode(true);
        const root = fragment.querySelector('.summary-panel');
        root.textContent = i18n$('dnrRulesCountInfo')
            .replace('{count}', (this.count || 0).toLocaleString())
        editor.updateSummaryPanel(root);
    }

    off(editor) {
        editor.updateSummaryPanel(null);
    }

    exportToFile(text) {
        return super.exportToFile(text, `${this.id}-dnr-ruleset.json`);
    }
};
