"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.cssMiddleWareManager = void 0;
const tslib_1 = require("tslib");
const color_normalize_1 = tslib_1.__importDefault(require("color-normalize"));
const enum_chrome_mapping_1 = require("tdf-devtools-protocol/dist/types/enum-chrome-mapping");
exports.cssMiddleWareManager = {
    downwardMiddleWareListMap: {
        [enum_chrome_mapping_1.ChromeCommand.CSSGetMatchedStylesForNode]: ({ msg, sendToDevtools }) => {
            // 类型收窄
            const commandRes = msg;
            commandRes.result.inlineStyle = CssDomainAdapter.conversionInlineStyle(commandRes.result.inlineStyle);
            return sendToDevtools(commandRes);
        },
        [enum_chrome_mapping_1.ChromeCommand.CSSGetComputedStyleForNode]: ({ msg, sendToDevtools }) => {
            const commandRes = msg;
            commandRes.result.computedStyle = CssDomainAdapter.conversionComputedStyle(commandRes.result.computedStyle);
            return sendToDevtools(commandRes);
        },
        [enum_chrome_mapping_1.ChromeCommand.CSSSetStyleTexts]: ({ msg, sendToDevtools }) => {
            const commandRes = msg;
            commandRes.result.styles = commandRes.result.styles.map((style) => CssDomainAdapter.conversionInlineStyle(style));
            return sendToDevtools(commandRes);
        },
    },
    upwardMiddleWareListMap: {
        [enum_chrome_mapping_1.ChromeCommand.CSSSetStyleTexts]: ({ msg, sendToApp }) => {
            const req = msg;
            req.params.edits = req.params.edits.map((data) => {
                const textList = data.text
                    .trim()
                    .split(';')
                    .reduce((ret, styleItem) => {
                    if (!styleItem.trim())
                        return ret;
                    const styleItems = styleItem.split(':');
                    const [name] = styleItems;
                    let [, ...values] = styleItems;
                    if (!CssDomainAdapter.shouldSkipStyle(name)) {
                        values[0] = values[0].trim();
                        if (name.toLowerCase().includes('color') && !/^\d+$/.test(values[0])) {
                            const rgba = CssDomainAdapter.transformRGBA(values[0]);
                            values = [String(CssDomainAdapter.rgbaToInt(rgba))];
                        }
                        ret.push(`${name}: ${values.join(':').trim()}`);
                    }
                    return ret;
                }, []);
                const totalCSSText = textList.join(';');
                return Object.assign(Object.assign({}, data), { range: Object.assign(Object.assign({}, data.range), { endColumn: totalCSSText.length }), text: totalCSSText });
            });
            return sendToApp(req);
        },
    },
};
class CssDomainAdapter {
    static intToRGBA(int32Color) {
        const int = int32Color << 0;
        // Converts 0xaarrggbb into 0xrrggbbaa
        const int32 = ((int << 8) | (int >>> 24)) >>> 0;
        const int8 = new Uint8Array(new Uint32Array([int32]).buffer).reverse();
        const r = int8[0];
        const g = int8[1];
        const b = int8[2];
        const a = Math.round((int8[3] / 255) * 100) / 100;
        return `rgba(${r}, ${g}, ${b}, ${a})`;
    }
    static rgbaToInt(stringColor) {
        const uint8 = color_normalize_1.default(stringColor, 'uint8');
        const int = Buffer.from(uint8).readUInt32BE(0);
        // Converts 0xrrggbbaa into 0xaarrggbb
        return ((int << 24) | (int >>> 8)) >>> 0;
    }
    static shouldSkipStyle(styleName) {
        return CssDomainAdapter.skipStyleList.some((name) => name.toString().trim().toLowerCase() === styleName.toString().trim().toLowerCase());
    }
    static conversionInlineStyle(style) {
        let totalCSSText = '';
        style.cssProperties = (style.cssProperties || []).reduce((ret, item) => {
            if (CssDomainAdapter.shouldSkipStyle(item.name))
                return ret;
            const cssText = `${item.name}: ${item.value}`;
            if (item.name.toLowerCase().includes('color')) {
                item.value = CssDomainAdapter.intToRGBA(parseInt(item.value, 10));
            }
            item.range = Object.assign(Object.assign({}, item.range), { startColumn: totalCSSText.length, endColumn: totalCSSText.length + cssText.length + 1 });
            totalCSSText += `${cssText}; `;
            ret.push(item);
            return ret;
        }, []);
        style.cssText = totalCSSText;
        style.range = Object.assign(Object.assign({}, style.range), { endColumn: totalCSSText.length });
        return style;
    }
    static conversionComputedStyle(style) {
        if (!style)
            return [];
        return style.reduce((ret, item) => {
            if (!CssDomainAdapter.shouldSkipStyle(item.name)) {
                if (item.name.toLowerCase().includes('color')) {
                    item.value = CssDomainAdapter.intToRGBA(parseInt(item.value, 10));
                }
                ret.push(item);
            }
            return ret;
        }, []);
    }
    /**
     * rgba 中 alpha 百分比转为小数点形式
     */
    static transformRGBA(colorText) {
        return colorText.trim().replace(/^rgba?\(([^()]+)\)$/i, (s, p1) => {
            const flag = p1.includes(',') ? ',' : ' ';
            const channelList = p1.split(flag);
            const r = channelList[0];
            const g = channelList[1];
            const b = channelList[2];
            let a = channelList.length > 3 ? channelList[channelList.length - 1] : 1;
            if (a.toString().includes('%')) {
                a = parseInt(a, 10) / 100;
            }
            return `rgba(${r}, ${g}, ${b}, ${a})`;
        });
    }
}
CssDomainAdapter.skipStyleList = ['backgroundImage', 'transform', 'shadowOffset'];
