import type webview from "@ohos:web.webview";
class BjcCov {
    coverage: {
        [key: string]: string | number;
    };
    constructor(covData: object) {
        const gcv = "__coverage__";
        let coverage = globalThis[gcv] || (globalThis[gcv] = {});
        if (!coverage[covData.path] && true) {
            coverage[covData.path] = covData;
        }
        this.coverage = coverage[covData.path];
    }
    instrumentFunction(func: number) {
        this.coverage.functions[func].count++;
        this.coverage.functions[func].regions[0].count++;
    }
    instrumentRegion(func: number, region: number) {
        this.coverage.functions[func].regions[region].count++;
    }
    instrumentReturn(func: number, retIdx: number) {
        this.coverage.functions[func].returnes[retIdx].count++;
    }
    instrumentBranch(func: number, branch: number, trueOrFalse: boolean) {
        if (trueOrFalse) {
            this.coverage.functions[func].branches[branch].trueCount++;
            for (let r of Object.values(this.coverage.functions[func].branches[branch].group)) {
                if (r !== branch) {
                    this.coverage.functions[func].branches[r as number].falseCount++;
                }
            }
        }
        else {
            this.coverage.functions[func].branches[branch].falseCount++;
        }
    }
}
let bjccovms8pf60i = new BjcCov({ version: "bjc v1.0.0", versionCode: 10000, path: "tencentqianwebview/src/main/ets/internal/RenderRecovery.ets", hash: "5c72b2c154ec3741106f2ca2620afeef5ce378b3033af51b42cb1f44827b887a", lineCnt: 90, count: 0, projectPath: "", functions: { 0: { name: "RenderRecovery.recover", count: 0, regions: { 0: { startLoc: { line: 32, col: 3 }, endLoc: { line: 40, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 37, col: 5 }, endLoc: { line: 40, col: 4 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 0 }, 1: { name: "anonymous_0", count: 0, regions: { 0: { startLoc: { line: 35, col: 23 }, endLoc: { line: 35, col: 33 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 1 }, 2: { name: "anonymous_1", count: 0, regions: { 0: { startLoc: { line: 37, col: 23 }, endLoc: { line: 39, col: 6 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 38, col: 7 }, endLoc: { line: 39, col: 6 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 2 }, 3: { name: "RenderRecovery.performRecover", count: 0, regions: { 0: { startLoc: { line: 46, col: 3 }, endLoc: { line: 67, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 53, col: 33 }, endLoc: { line: 60, col: 6 }, count: 0, ignored: 0 }, 2: { startLoc: { line: 54, col: 11 }, endLoc: { line: 57, col: 8 }, count: 0, ignored: 0 }, 3: { startLoc: { line: 57, col: 9 }, endLoc: { line: 59, col: 8 }, count: 0, ignored: 0 }, 4: { startLoc: { line: 62, col: 9 }, endLoc: { line: 64, col: 6 }, count: 0, ignored: 0 }, 5: { startLoc: { line: 64, col: 7 }, endLoc: { line: 66, col: 6 }, count: 0, ignored: 0 } }, branches: { 0: { startLoc: { line: 53, col: 9 }, endLoc: { line: 53, col: 31 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 } }, ignored: 0, index: 3 }, 4: { name: "anonymous_2", count: 0, regions: { 0: { startLoc: { line: 49, col: 23 }, endLoc: { line: 49, col: 33 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 4 }, 5: { name: "RenderRecovery.fireUnrecoverable", count: 0, regions: { 0: { startLoc: { line: 69, col: 3 }, endLoc: { line: 73, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 70, col: 27 }, endLoc: { line: 72, col: 6 }, count: 0, ignored: 0 } }, branches: { 0: { startLoc: { line: 70, col: 9 }, endLoc: { line: 70, col: 25 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 } }, ignored: 0, index: 5 }, 6: { name: "anonymous_3", count: 0, regions: { 0: { startLoc: { line: 69, col: 41 }, endLoc: { line: 69, col: 51 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 6 }, 7: { name: "captureLastUrl", count: 0, regions: { 0: { startLoc: { line: 79, col: 3 }, endLoc: { line: 86, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 80, col: 9 }, endLoc: { line: 83, col: 6 }, count: 0, ignored: 0 }, 2: { startLoc: { line: 83, col: 7 }, endLoc: { line: 85, col: 6 }, count: 0, ignored: 0 } }, branches: { 0: { startLoc: { line: 82, col: 14 }, endLoc: { line: 82, col: 83 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 } }, ignored: 0, index: 7 }, 8: { name: "RenderRecovery.constructor", count: 0, regions: { 0: { startLoc: { line: 88, col: 3 }, endLoc: { line: 88, col: 27 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 8 } }, exeLine: { 0: 1, 1: 16, 2: 18, 3: 32, 4: 33, 5: 34, 6: 35, 7: 36, 8: 37, 9: 38, 10: 39, 11: 46, 12: 47, 13: 48, 14: 49, 15: 50, 16: 53, 17: 54, 18: 55, 19: 56, 20: 57, 21: 62, 22: 63, 23: 64, 24: 65, 25: 69, 26: 70, 27: 71, 28: 79, 29: 80, 30: 81, 31: 82, 32: 83, 33: 84, 34: 88 } });
/**
 * 渲染进程异常后的页面恢复策略。
 *
 * 渲染进程被系统回收后 Web 组件不会自动恢复,需主动重载,否则页面卡死/白屏。
 * 恢复链:`loadUrl(fallbackUrl)` → `refresh()` → `onUnrecoverable()`。
 *
 * **为何 loadUrl 优先于 refresh**:进程崩溃后内部状态未清,`refresh()`/`reload()` 常失效
 * (甚至不抛错却也未真正恢复),`loadUrl()` 能强制重建渲染管线。与 Android(新建实例后 loadUrl)、
 * iOS(优先 load(URLRequest))对齐,亦符合社区推荐。
 *
 * **延迟恢复**:崩溃后立即 reload 可能因内存/资源仍紧张而再次崩溃(尤其 OOM 场景),
 * 故延迟 `RECOVER_DELAY_MS` 再执行,给系统留出资源回收窗口(对齐社区实践)。
 */
export class RenderRecovery {
    /** 崩溃后延迟恢复的毫秒数,避免瞬间抢占资源再次崩溃。 */
    private static readonly RECOVER_DELAY_MS: number = 1000;
    /**
     * 尝试恢复 Web 组件(延迟 `RECOVER_DELAY_MS` 后执行,避免瞬间再次崩溃)。
     *
     * **重要**:返回的 timer id 必须由调用方保存,并在容器销毁/归还池时 `clearTimeout` 取消,
     * 否则延迟窗口内用户关闭页面后,回调仍会访问已销毁/已归还的 controller,导致无效 reload
     * 或污染已归还的池实例(野指针)。
     *
     * @param controller WebviewController
     * @param fallbackUrl 优先用以 `loadUrl` 重载的 URL;空串表示无可用 URL(退化为 `refresh` 兜底)
     * @param onUnrecoverable 全部尝试失败时的回调(如关闭容器)
     * @returns 延迟恢复的 timer id,供调用方在生命周期结束时 `clearTimeout` 取消
     */
    public static recover(controller: webview.WebviewController, fallbackUrl: string, onUnrecoverable?: () => void): number {
        bjccovms8pf60i.instrumentFunction(0);
        bjccovms8pf60i.instrumentRegion(0, 1);
        return setTimeout(() => {
            bjccovms8pf60i.instrumentFunction(2);
            bjccovms8pf60i.instrumentRegion(2, 1);
            RenderRecovery.performRecover(controller, fallbackUrl, onUnrecoverable);
        }, RenderRecovery.RECOVER_DELAY_MS);
    }
    /**
     * 立即执行一次恢复尝试(同步)。恢复链:`loadUrl(fallbackUrl)` → `refresh()` → `onUnrecoverable()`。
     * 供 {@link recover} 延迟调度调用,亦便于单测同步验证。
     */
    public static performRecover(controller: webview.WebviewController, fallbackUrl: string, onUnrecoverable?: () => void): void {
        bjccovms8pf60i.instrumentFunction(3);
        // 优先 loadUrl(fallbackUrl):进程崩溃后 refresh() 常因内部状态未清而失效,loadUrl 能强制重建渲染管线
        // (与 Android/iOS 恢复方式对齐,符合社区推荐)。
        if (fallbackUrl.length > 0) {
            bjccovms8pf60i.instrumentBranch(3, 0, true);
            bjccovms8pf60i.instrumentRegion(3, 1);
            try {
                bjccovms8pf60i.instrumentRegion(3, 2);
                controller.loadUrl(fallbackUrl);
                return;
            }
            catch (_e) {
                bjccovms8pf60i.instrumentRegion(3, 3);
            }
        }
        // 无可用 URL / loadUrl 失败 → 退化尝试 refresh;仍失败则判定不可恢复(触发关闭容器)。
        else {
            bjccovms8pf60i.instrumentBranch(3, 0, false);
        }
        // 无可用 URL / loadUrl 失败 → 退化尝试 refresh;仍失败则判定不可恢复(触发关闭容器)。
        try {
            bjccovms8pf60i.instrumentRegion(3, 4);
            controller.refresh();
        }
        catch (_e) {
            bjccovms8pf60i.instrumentRegion(3, 5);
            RenderRecovery.fireUnrecoverable(onUnrecoverable);
        }
    }
    private static fireUnrecoverable(cb?: () => void): void {
        bjccovms8pf60i.instrumentFunction(5);
        if (cb !== undefined) {
            bjccovms8pf60i.instrumentBranch(5, 0, true);
            bjccovms8pf60i.instrumentRegion(5, 1);
            cb();
        }
        else /**
         * 从 `onPageBegin` 事件中提取主框架 URL,用于 `recover()` 的 fallback 兜底。
         * 提取失败返回 `current`,不覆盖原值。
         */ {
            bjccovms8pf60i.instrumentBranch(5, 0, false);
        }
    }
    /**
     * 从 `onPageBegin` 事件中提取主框架 URL,用于 `recover()` 的 fallback 兜底。
     * 提取失败返回 `current`,不覆盖原值。
     */
    public static captureLastUrl(event: any, current: string): string {
        bjccovms8pf60i.instrumentFunction(7);
        try {
            bjccovms8pf60i.instrumentRegion(7, 1);
            const url: string = (event as any).url as string;
            return (url !== null && url !== undefined && url.length > 0) ? (bjccovms8pf60i.instrumentBranch(7, 0, true), url) : (bjccovms8pf60i.instrumentBranch(7, 0, false), current);
        }
        catch (_e) {
            bjccovms8pf60i.instrumentRegion(7, 2);
            return current;
        }
    }
    private constructor() { bjccovms8pf60i.instrumentFunction(8); }
}
