import type common from "@ohos:app.ability.common";
import type { TencentQianWebViewConfig } from '../model/TencentQianWebViewConfig';
import type { OnSignResult, OnSdkEvent } from '../model/SignCallback';
import { SchemeInterceptedEvent, SchemeNotMatchedEvent, DownloadFailedEvent } from "@normalized:N&&&tencentqianwebview/src/main/ets/model/SdkEvent&1.0.0";
import { SignResultParser } from "@normalized:N&&&tencentqianwebview/src/main/ets/scheme/SignResultParser&1.0.0";
import { ExternalSchemeHandler } from "@normalized:N&&&tencentqianwebview/src/main/ets/scheme/ExternalSchemeHandler&1.0.0";
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 bjccovms5u83s9 = new BjcCov({ version: "bjc v1.0.0", versionCode: 10000, path: "tencentqianwebview/src/main/ets/scheme/SchemeInterceptor.ets", hash: "03da83b16549af963bf868fab0d1dae6c569772ee5bb53200b5d7d8cff3310d2", lineCnt: 160, count: 0, projectPath: "", functions: { 0: { name: "anonymous_0", count: 0, regions: { 0: { startLoc: { line: 13, col: 32 }, endLoc: { line: 13, col: 53 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 0 }, 1: { name: "SchemeInterceptor.constructor", count: 0, regions: { 0: { startLoc: { line: 42, col: 3 }, endLoc: { line: 54, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 49, col: 5 }, endLoc: { line: 54, col: 4 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 1 }, 2: { name: "SchemeInterceptor.intercept", count: 0, regions: { 0: { startLoc: { line: 62, col: 3 }, endLoc: { line: 93, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 63, col: 64 }, endLoc: { line: 65, col: 6 }, count: 0, ignored: 0 }, 2: { startLoc: { line: 67, col: 48 }, endLoc: { line: 69, col: 6 }, count: 0, ignored: 0 }, 3: { startLoc: { line: 73, col: 28 }, endLoc: { line: 76, col: 6 }, count: 0, ignored: 0 }, 4: { startLoc: { line: 78, col: 50 }, endLoc: { line: 80, col: 6 }, count: 0, ignored: 0 }, 5: { startLoc: { line: 82, col: 77 }, endLoc: { line: 84, col: 6 }, count: 0, ignored: 0 }, 6: { startLoc: { line: 86, col: 80 }, endLoc: { line: 89, col: 6 }, count: 0, ignored: 0 }, 7: { startLoc: { line: 91, col: 5 }, endLoc: { line: 93, col: 4 }, count: 0, ignored: 0 } }, branches: { 0: { startLoc: { line: 63, col: 9 }, endLoc: { line: 63, col: 62 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 }, 1: { startLoc: { line: 67, col: 9 }, endLoc: { line: 67, col: 46 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 }, 2: { startLoc: { line: 73, col: 9 }, endLoc: { line: 73, col: 26 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 }, 3: { startLoc: { line: 78, col: 9 }, endLoc: { line: 78, col: 48 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 }, 4: { startLoc: { line: 82, col: 9 }, endLoc: { line: 82, col: 75 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 }, 5: { startLoc: { line: 86, col: 9 }, endLoc: { line: 86, col: 78 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 } }, ignored: 0, index: 2 }, 3: { name: "SchemeInterceptor.handleQianApp", count: 0, regions: { 0: { startLoc: { line: 96, col: 3 }, endLoc: { line: 104, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 98, col: 9 }, endLoc: { line: 100, col: 6 }, count: 0, ignored: 0 }, 2: { startLoc: { line: 100, col: 7 }, endLoc: { line: 102, col: 6 }, count: 0, ignored: 0 }, 3: { startLoc: { line: 103, col: 5 }, endLoc: { line: 104, col: 4 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 3 }, 4: { name: "SchemeInterceptor.handleHttpUrl", count: 0, regions: { 0: { startLoc: { line: 107, col: 3 }, endLoc: { line: 118, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 108, col: 74 }, endLoc: { line: 110, col: 6 }, count: 0, ignored: 0 }, 2: { startLoc: { line: 112, col: 9 }, endLoc: { line: 114, col: 6 }, count: 0, ignored: 0 }, 3: { startLoc: { line: 114, col: 7 }, endLoc: { line: 116, col: 6 }, count: 0, ignored: 0 }, 4: { startLoc: { line: 117, col: 5 }, endLoc: { line: 118, col: 4 }, count: 0, ignored: 0 } }, branches: { 0: { startLoc: { line: 108, col: 9 }, endLoc: { line: 108, col: 72 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 } }, ignored: 0, index: 4 }, 5: { name: "SchemeInterceptor.handleExternalScheme", count: 0, regions: { 0: { startLoc: { line: 121, col: 3 }, endLoc: { line: 128, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 122, col: 5 }, endLoc: { line: 128, col: 4 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 5 }, 6: { name: "anonymous_1", count: 0, regions: { 0: { startLoc: { line: 123, col: 56 }, endLoc: { line: 127, col: 6 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 124, col: 16 }, endLoc: { line: 126, col: 8 }, count: 0, ignored: 0 } }, branches: { 0: { startLoc: { line: 124, col: 11 }, endLoc: { line: 124, col: 14 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 } }, ignored: 0, index: 6 }, 7: { name: "SchemeInterceptor.emitBlobUnsupported", count: 0, regions: { 0: { startLoc: { line: 130, col: 3 }, endLoc: { line: 133, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 131, col: 5 }, endLoc: { line: 133, col: 4 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 7 }, 8: { name: "SchemeInterceptor.emitSchemeNotMatched", count: 0, regions: { 0: { startLoc: { line: 135, col: 3 }, endLoc: { line: 137, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 136, col: 5 }, endLoc: { line: 137, col: 4 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 8 }, 9: { name: "SchemeInterceptor.emitEvent", count: 0, regions: { 0: { startLoc: { line: 139, col: 3 }, endLoc: { line: 143, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 140, col: 40 }, endLoc: { line: 142, col: 6 }, count: 0, ignored: 0 } }, branches: { 0: { startLoc: { line: 140, col: 9 }, endLoc: { line: 140, col: 38 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 } }, ignored: 0, index: 9 }, 10: { name: "SchemeInterceptor.isDownloadUrl", count: 0, regions: { 0: { startLoc: { line: 146, col: 3 }, endLoc: { line: 158, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 147, col: 9 }, endLoc: { line: 154, col: 6 }, count: 0, ignored: 0 }, 2: { startLoc: { line: 154, col: 7 }, endLoc: { line: 156, col: 6 }, count: 0, ignored: 0 }, 3: { startLoc: { line: 149, col: 7 }, endLoc: { line: 153, col: 8 }, count: 0, ignored: 0 }, 4: { startLoc: { line: 150, col: 36 }, endLoc: { line: 152, col: 10 }, count: 0, ignored: 0 }, 5: { startLoc: { line: 157, col: 5 }, endLoc: { line: 158, col: 4 }, count: 0, ignored: 0 } }, branches: { 0: { startLoc: { line: 150, col: 13 }, endLoc: { line: 150, col: 34 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 } }, ignored: 0, index: 10 } }, exeLine: { 0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10, 10: 13, 11: 26, 12: 28, 13: 29, 14: 30, 15: 31, 16: 32, 17: 33, 18: 36, 19: 37, 20: 38, 21: 39, 22: 40, 23: 43, 24: 44, 25: 45, 26: 46, 27: 47, 28: 48, 29: 49, 30: 50, 31: 51, 32: 52, 33: 53, 34: 62, 35: 63, 36: 64, 37: 67, 38: 68, 39: 71, 40: 73, 41: 74, 42: 75, 43: 78, 44: 79, 45: 82, 46: 83, 47: 86, 48: 87, 49: 88, 50: 91, 51: 92, 52: 96, 53: 97, 54: 98, 55: 99, 56: 100, 57: 103, 58: 107, 59: 108, 60: 109, 61: 111, 62: 112, 63: 113, 64: 114, 65: 117, 66: 121, 67: 122, 68: 123, 69: 124, 70: 125, 71: 130, 72: 131, 73: 132, 74: 135, 75: 136, 76: 139, 77: 140, 78: 141, 79: 146, 80: 147, 81: 148, 82: 149, 83: 150, 84: 151, 85: 154, 86: 157 } });
/** 主框架疑似下载链接的回调,容器侧据此走 DownloadHandler。 */
export type OnDirectDownload = (url: string) => void;
/**
 * Scheme 拦截层(SDK 内部使用)。
 *
 * 对 Web 即将加载的 URL 做归类处理:
 * - `qianapp://` → 解析为 SignResult,触发 `onSignResult` 回调
 * - 白名单外部 scheme(weixin / alipays 等)→ startAbility 跳出本 App
 * - 主框架 http(s) 链接后缀疑似下载 → 走 DownloadHandler
 * - `blob:` → 暂不支持,通过 `DownloadFailed` 事件提示客户
 * - 其余 http(s) / about / data / javascript → 放行 Web 组件加载
 * - 未匹配的 scheme → 丢弃并通过 `SchemeNotMatched` 事件上报
 */
export class SchemeInterceptor {
    /** 直连下载的文件后缀白名单(对齐 Android 下载行为)。 */
    private static readonly DOWNLOAD_SUFFIXES: string[] = [
        '.pdf', '.doc', '.docx', '.xls', '.xlsx', '.csv', '.ppt', '.pptx',
        '.txt', '.zip', '.rar', '.7z', '.tar', '.gz',
        '.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp',
        '.mp3', '.mp4', '.m4a', '.wav', '.avi', '.mov',
        '.apk', '.hap'
    ];
    private context: common.UIAbilityContext;
    private config: TencentQianWebViewConfig;
    private onSignResult: OnSignResult;
    private onSdkEvent?: OnSdkEvent;
    private onDirectDownload?: OnDirectDownload;
    constructor(context: common.UIAbilityContext, config: TencentQianWebViewConfig, onSignResult: OnSignResult, onSdkEvent?: OnSdkEvent, onDirectDownload?: OnDirectDownload) {
        bjccovms5u83s9.instrumentFunction(1);
        bjccovms5u83s9.instrumentRegion(1, 1);
        this.context = context;
        this.config = config;
        this.onSignResult = onSignResult;
        this.onSdkEvent = onSdkEvent;
        this.onDirectDownload = onDirectDownload;
    }
    /**
     * 拦截判定。
     *
     * @param url 即将加载的 URL
     * @returns true = SDK 已处理,Web 组件应取消导航;false = 放行
     */
    public intercept(url: string): boolean {
        bjccovms5u83s9.instrumentFunction(2);
        if (url === null || url === undefined || url.length === 0) {
            bjccovms5u83s9.instrumentBranch(2, 0, true);
            bjccovms5u83s9.instrumentRegion(2, 1);
            return false;
        }
        else {
            bjccovms5u83s9.instrumentBranch(2, 0, false);
        }
        if (SignResultParser.isQianAppScheme(url)) {
            bjccovms5u83s9.instrumentBranch(2, 1, true);
            bjccovms5u83s9.instrumentRegion(2, 2);
            return this.handleQianApp(url);
        }
        else {
            bjccovms5u83s9.instrumentBranch(2, 1, false);
        }
        const scheme: string = ExternalSchemeHandler.schemeOf(url);
        if (scheme === 'blob') {
            bjccovms5u83s9.instrumentBranch(2, 2, true);
            bjccovms5u83s9.instrumentRegion(2, 3);
            this.emitBlobUnsupported(url);
            return true;
        }
        else {
            bjccovms5u83s9.instrumentBranch(2, 2, false);
        }
        if (scheme === 'http' || scheme === 'https') {
            bjccovms5u83s9.instrumentBranch(2, 3, true);
            bjccovms5u83s9.instrumentRegion(2, 4);
            return this.handleHttpUrl(url);
        }
        else {
            bjccovms5u83s9.instrumentBranch(2, 3, false);
        }
        if (scheme === 'about' || scheme === 'data' || scheme === 'javascript') {
            bjccovms5u83s9.instrumentBranch(2, 4, true);
            bjccovms5u83s9.instrumentRegion(2, 5);
            return false;
        }
        else {
            bjccovms5u83s9.instrumentBranch(2, 4, false);
        }
        if (ExternalSchemeHandler.isWhitelisted(url, this.config.externalSchemes)) {
            bjccovms5u83s9.instrumentBranch(2, 5, true);
            bjccovms5u83s9.instrumentRegion(2, 6);
            this.handleExternalScheme(scheme, url);
            return true;
        }
        else {
            bjccovms5u83s9.instrumentBranch(2, 5, false);
        }
        bjccovms5u83s9.instrumentRegion(2, 7);
        this.emitSchemeNotMatched(url);
        return true;
    }
    /** 解析 `qianapp://` 并触发 `onSignResult` 回调。 */
    private handleQianApp(url: string): boolean {
        bjccovms5u83s9.instrumentFunction(3);
        this.emitEvent(new SchemeInterceptedEvent('qianapp', url));
        try {
            bjccovms5u83s9.instrumentRegion(3, 1);
            this.onSignResult(SignResultParser.parse(url));
        }
        catch (_e) {
            bjccovms5u83s9.instrumentRegion(3, 2);
        }
        bjccovms5u83s9.instrumentRegion(3, 3);
        return true;
    }
    /** http(s) 链接:后缀疑似下载交给 DownloadHandler,否则放行 Web 组件。 */
    private handleHttpUrl(url: string): boolean {
        bjccovms5u83s9.instrumentFunction(4);
        if (!this.isDownloadUrl(url) || this.onDirectDownload === undefined) {
            bjccovms5u83s9.instrumentBranch(4, 0, true);
            bjccovms5u83s9.instrumentRegion(4, 1);
            return false;
        }
        else {
            bjccovms5u83s9.instrumentBranch(4, 0, false);
        }
        this.emitEvent(new SchemeInterceptedEvent('download', url));
        try {
            bjccovms5u83s9.instrumentRegion(4, 2);
            this.onDirectDownload(url);
        }
        catch (_e) {
            bjccovms5u83s9.instrumentRegion(4, 3);
        }
        bjccovms5u83s9.instrumentRegion(4, 4);
        return true;
    }
    /** 白名单外部 scheme:`startAbility` 跳出本 App;失败上报 SchemeNotMatched。 */
    private handleExternalScheme(scheme: string, url: string): void {
        bjccovms5u83s9.instrumentFunction(5);
        bjccovms5u83s9.instrumentRegion(5, 1);
        this.emitEvent(new SchemeInterceptedEvent(scheme, url));
        ExternalSchemeHandler.open(this.context, url).then((ok: boolean) => {
            bjccovms5u83s9.instrumentFunction(6);
            if (!ok) {
                bjccovms5u83s9.instrumentBranch(6, 0, true);
                bjccovms5u83s9.instrumentRegion(6, 1);
                this.emitSchemeNotMatched(url);
            }
            else {
                bjccovms5u83s9.instrumentBranch(6, 0, false);
            }
        });
    }
    private emitBlobUnsupported(url: string): void {
        bjccovms5u83s9.instrumentFunction(7);
        bjccovms5u83s9.instrumentRegion(7, 1);
        this.emitEvent(new SchemeInterceptedEvent('blob', url));
        this.emitEvent(new DownloadFailedEvent(url, 'blob 下载暂不支持,请通过 JSBridge 自行实现'));
    }
    private emitSchemeNotMatched(url: string): void {
        bjccovms5u83s9.instrumentFunction(8);
        bjccovms5u83s9.instrumentRegion(8, 1);
        this.emitEvent(new SchemeNotMatchedEvent(url));
    }
    private emitEvent(event: SchemeInterceptedEvent | SchemeNotMatchedEvent | DownloadFailedEvent): void {
        bjccovms5u83s9.instrumentFunction(9);
        if (this.onSdkEvent !== undefined) {
            bjccovms5u83s9.instrumentBranch(9, 0, true);
            bjccovms5u83s9.instrumentRegion(9, 1);
            this.onSdkEvent(event);
        }
        else /** 根据 URL 路径后缀判断是否疑似下载链接。 */ {
            bjccovms5u83s9.instrumentBranch(9, 0, false);
        }
    }
    /** 根据 URL 路径后缀判断是否疑似下载链接。 */
    private isDownloadUrl(url: string): boolean {
        bjccovms5u83s9.instrumentFunction(10);
        try {
            bjccovms5u83s9.instrumentRegion(10, 1);
            const path: string = url.split('?')[0].split('#')[0].toLowerCase();
            for (const suffix of SchemeInterceptor.DOWNLOAD_SUFFIXES) {
                bjccovms5u83s9.instrumentRegion(10, 3);
                if (path.endsWith(suffix)) {
                    bjccovms5u83s9.instrumentBranch(10, 0, true);
                    bjccovms5u83s9.instrumentRegion(10, 4);
                    return true;
                }
                else {
                    bjccovms5u83s9.instrumentBranch(10, 0, false);
                }
            }
        }
        catch (_e) {
            bjccovms5u83s9.instrumentRegion(10, 2);
        }
        bjccovms5u83s9.instrumentRegion(10, 5);
        return false;
    }
}
