import { SignResult } from "@normalized:N&&&tencentqianwebview/src/main/ets/model/SignResult&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 bjccovms5u83tl = new BjcCov({ version: "bjc v1.0.0", versionCode: 10000, path: "tencentqianwebview/src/main/ets/scheme/SignResultParser.ets", hash: "542095ccd801df7759358d171fd00ab32de5c7db0653f4f26569dab5b2848147", lineCnt: 153, count: 0, projectPath: "", functions: { 0: { name: "SignResultParser.isQianAppScheme", count: 0, regions: { 0: { startLoc: { line: 26, col: 3 }, endLoc: { line: 31, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 27, col: 64 }, endLoc: { line: 29, col: 6 }, count: 0, ignored: 0 }, 2: { startLoc: { line: 30, col: 5 }, endLoc: { line: 31, col: 4 }, count: 0, ignored: 0 } }, branches: { 0: { startLoc: { line: 27, col: 9 }, endLoc: { line: 27, col: 62 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 } }, ignored: 0, index: 0 }, 1: { name: "SignResultParser.parse", count: 0, regions: { 0: { startLoc: { line: 40, col: 3 }, endLoc: { line: 78, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 41, col: 64 }, endLoc: { line: 43, col: 6 }, count: 0, ignored: 0 }, 2: { startLoc: { line: 44, col: 49 }, endLoc: { line: 46, col: 6 }, count: 0, ignored: 0 }, 3: { startLoc: { line: 47, col: 55 }, endLoc: { line: 49, col: 6 }, count: 0, ignored: 0 }, 4: { startLoc: { line: 52, col: 5 }, endLoc: { line: 78, col: 4 }, count: 0, ignored: 0 } }, branches: { 0: { startLoc: { line: 41, col: 9 }, endLoc: { line: 41, col: 62 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 }, 1: { startLoc: { line: 44, col: 9 }, endLoc: { line: 44, col: 47 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 }, 2: { startLoc: { line: 47, col: 9 }, endLoc: { line: 47, col: 53 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 }, 3: { startLoc: { line: 64, col: 28 }, endLoc: { line: 64, col: 88 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 }, 4: { startLoc: { line: 65, col: 28 }, endLoc: { line: 65, col: 88 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 }, 5: { startLoc: { line: 66, col: 28 }, endLoc: { line: 66, col: 88 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 }, 6: { startLoc: { line: 67, col: 26 }, endLoc: { line: 67, col: 82 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 } }, ignored: 0, index: 1 }, 2: { name: "anonymous_0", count: 0, regions: { 0: { startLoc: { line: 71, col: 20 }, endLoc: { line: 75, col: 6 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 72, col: 62 }, endLoc: { line: 74, col: 8 }, count: 0, ignored: 0 } }, branches: { 0: { startLoc: { line: 72, col: 11 }, endLoc: { line: 72, col: 60 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 } }, ignored: 0, index: 2 }, 3: { name: "SignResultParser.splitOnce", count: 0, regions: { 0: { startLoc: { line: 81, col: 3 }, endLoc: { line: 87, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 83, col: 18 }, endLoc: { line: 85, col: 6 }, count: 0, ignored: 0 }, 2: { startLoc: { line: 86, col: 5 }, endLoc: { line: 87, col: 4 }, count: 0, ignored: 0 } }, branches: { 0: { startLoc: { line: 83, col: 9 }, endLoc: { line: 83, col: 16 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 } }, ignored: 0, index: 3 }, 4: { name: "SignResultParser.trimSlashes", count: 0, regions: { 0: { startLoc: { line: 90, col: 3 }, endLoc: { line: 100, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 93, col: 5 }, endLoc: { line: 95, col: 6 }, count: 0, ignored: 0 }, 2: { startLoc: { line: 96, col: 5 }, endLoc: { line: 98, col: 6 }, count: 0, ignored: 0 }, 3: { startLoc: { line: 99, col: 5 }, endLoc: { line: 100, col: 4 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 4 }, 5: { name: "SignResultParser.parseQuery", count: 0, regions: { 0: { startLoc: { line: 109, col: 3 }, endLoc: { line: 137, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 111, col: 29 }, endLoc: { line: 113, col: 6 }, count: 0, ignored: 0 }, 2: { startLoc: { line: 116, col: 5 }, endLoc: { line: 135, col: 6 }, count: 0, ignored: 0 }, 3: { startLoc: { line: 118, col: 30 }, endLoc: { line: 120, col: 8 }, count: 0, ignored: 0 }, 4: { startLoc: { line: 126, col: 45 }, endLoc: { line: 128, col: 8 }, count: 0, ignored: 0 }, 5: { startLoc: { line: 130, col: 25 }, endLoc: { line: 132, col: 8 }, count: 0, ignored: 0 }, 6: { startLoc: { line: 136, col: 5 }, endLoc: { line: 137, col: 4 }, count: 0, ignored: 0 }, 7: { startLoc: { line: 133, col: 7 }, endLoc: { line: 135, col: 6 }, count: 0, ignored: 0 } }, branches: { 0: { startLoc: { line: 111, col: 9 }, endLoc: { line: 111, col: 27 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 }, 1: { startLoc: { line: 118, col: 11 }, endLoc: { line: 118, col: 28 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 }, 2: { startLoc: { line: 126, col: 11 }, endLoc: { line: 126, col: 43 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 }, 3: { startLoc: { line: 130, col: 11 }, endLoc: { line: 130, col: 23 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 }, 4: { startLoc: { line: 134, col: 20 }, endLoc: { line: 134, col: 47 }, trueCount: 0, falseCount: 0, group: {}, ignored: 0 } }, ignored: 0, index: 5 }, 6: { name: "SignResultParser.decodeOrNull", count: 0, regions: { 0: { startLoc: { line: 143, col: 3 }, endLoc: { line: 151, col: 4 }, count: 0, ignored: 0 }, 1: { startLoc: { line: 144, col: 9 }, endLoc: { line: 148, col: 6 }, count: 0, ignored: 0 }, 2: { startLoc: { line: 148, col: 7 }, endLoc: { line: 150, col: 6 }, count: 0, ignored: 0 } }, branches: {}, ignored: 0, index: 6 } }, exeLine: { 0: 1, 1: 14, 2: 15, 3: 16, 4: 19, 5: 21, 6: 26, 7: 27, 8: 28, 9: 30, 10: 40, 11: 41, 12: 42, 13: 44, 14: 45, 15: 47, 16: 48, 17: 52, 18: 53, 19: 54, 20: 55, 21: 58, 22: 61, 23: 64, 24: 65, 25: 66, 26: 67, 27: 70, 28: 71, 29: 72, 30: 73, 31: 77, 32: 81, 33: 82, 34: 83, 35: 84, 36: 86, 37: 90, 38: 91, 39: 92, 40: 93, 41: 94, 42: 96, 43: 97, 44: 99, 45: 109, 46: 110, 47: 111, 48: 112, 49: 115, 50: 116, 51: 117, 52: 118, 53: 119, 54: 121, 55: 122, 56: 123, 57: 125, 58: 126, 59: 127, 60: 130, 61: 131, 62: 133, 63: 134, 64: 136, 65: 143, 66: 144, 67: 146, 68: 147, 69: 148, 70: 149 } });
/**
 * `qianapp://` 协议解析器(纯函数,客户也可在 SDK 容器外直接调用)。
 *
 * **解析约定**:
 * - host + path 拼接为 `customPath`(去除前后斜杠)
 * - query 按 `application/x-www-form-urlencoded` 语义 UTF-8 解码,`+` 等价空格
 * - 重复 key 保留**首个**,空 value(`?action=`)保留为空字符串
 * - 已知字段(`flowId` / `action` / `result` / `from`)抽出到对应字段;未知字段透传到 `extras`
 * - action / result 未识别值原样透出(SDK 不做收敛)
 * - 非法 URL / scheme 不匹配 / 长度超过 8KB → 返回 `SignResult.EMPTY`
 */
export class SignResultParser {
    private static readonly SCHEME: string = 'qianapp';
    private static readonly SCHEME_PREFIX: string = 'qianapp://';
    /** URL 最大长度限制(8KB),超过视为恶意构造,返回 SignResult.EMPTY 并丢弃。 */
    private static readonly MAX_URL_LENGTH: number = 8 * 1024;
    private static readonly RECOGNIZED_KEYS: string[] = ['flowId', 'action', 'result', 'from'];
    /**
     * 判断给定 URL 是否为本 SDK 关心的 `qianapp://` scheme(大小写不敏感)。
     */
    public static isQianAppScheme(url: string | null | undefined): boolean {
        bjccovms5u83tl.instrumentFunction(0);
        if (url === null || url === undefined || url.length === 0) {
            bjccovms5u83tl.instrumentBranch(0, 0, true);
            bjccovms5u83tl.instrumentRegion(0, 1);
            return false;
        }
        else {
            bjccovms5u83tl.instrumentBranch(0, 0, false);
        }
        bjccovms5u83tl.instrumentRegion(0, 2);
        return url.toLowerCase().startsWith(SignResultParser.SCHEME_PREFIX);
    }
    /**
     * 解析 `qianapp://...` URL。
     *
     * 失败时返回 SignResult.EMPTY。
     *
     * @param url 完整 URL,例 `qianapp://callback/sign?flowId=abc&action=sign&result=success&from=tencent_ess`
     */
    public static parse(url: string | null | undefined): SignResult {
        bjccovms5u83tl.instrumentFunction(1);
        if (url === null || url === undefined || url.length === 0) {
            bjccovms5u83tl.instrumentBranch(1, 0, true);
            bjccovms5u83tl.instrumentRegion(1, 1);
            return SignResult.EMPTY;
        }
        else {
            bjccovms5u83tl.instrumentBranch(1, 0, false);
        }
        if (!SignResultParser.isQianAppScheme(url)) {
            bjccovms5u83tl.instrumentBranch(1, 1, true);
            bjccovms5u83tl.instrumentRegion(1, 2);
            return SignResult.EMPTY;
        }
        else {
            bjccovms5u83tl.instrumentBranch(1, 1, false);
        }
        if (url.length > SignResultParser.MAX_URL_LENGTH) {
            bjccovms5u83tl.instrumentBranch(1, 2, true);
            bjccovms5u83tl.instrumentRegion(1, 3);
            return SignResult.EMPTY;
        }
        // 拆 scheme://body[?query]
        else {
            bjccovms5u83tl.instrumentBranch(1, 2, false);
        }
        bjccovms5u83tl.instrumentRegion(1, 4);
        // 拆 scheme://body[?query]
        const body: string = url.substring(SignResultParser.SCHEME_PREFIX.length);
        const splitBody: [
            string,
            string
        ] = SignResultParser.splitOnce(body, '?');
        const pathPart: string = splitBody[0];
        const queryPart: string = splitBody[1];
        // host + path 即为 customPath, 去除前后斜杠
        const customPath: string = SignResultParser.trimSlashes(pathPart);
        // 解析 query
        const parsed: Map<string, string> = SignResultParser.parseQuery(queryPart);
        // 抽出 recognized fields
        const flowId: string = parsed.has('flowId') ? (bjccovms5u83tl.instrumentBranch(1, 3, true), (parsed.get('flowId') as string)) : (bjccovms5u83tl.instrumentBranch(1, 3, false), '');
        const action: string = parsed.has('action') ? (bjccovms5u83tl.instrumentBranch(1, 4, true), (parsed.get('action') as string)) : (bjccovms5u83tl.instrumentBranch(1, 4, false), '');
        const result: string = parsed.has('result') ? (bjccovms5u83tl.instrumentBranch(1, 5, true), (parsed.get('result') as string)) : (bjccovms5u83tl.instrumentBranch(1, 5, false), '');
        const from: string = parsed.has('from') ? (bjccovms5u83tl.instrumentBranch(1, 6, true), (parsed.get('from') as string)) : (bjccovms5u83tl.instrumentBranch(1, 6, false), '');
        // 剩余 query 落入 extras
        const extras: Map<string, string> = new Map<string, string>();
        parsed.forEach((value: string, key: string) => {
            bjccovms5u83tl.instrumentFunction(2);
            if (SignResultParser.RECOGNIZED_KEYS.indexOf(key) < 0) {
                bjccovms5u83tl.instrumentBranch(2, 0, true);
                bjccovms5u83tl.instrumentRegion(2, 1);
                extras.set(key, value);
            }
            else {
                bjccovms5u83tl.instrumentBranch(2, 0, false);
            }
        });
        return new SignResult(url, customPath, flowId, action, result, from, extras);
    }
    /** 在第一个 [delimiter] 上拆分,返回 [左, 右]。无分隔符时右半为空字符串。 */
    private static splitOnce(input: string, delimiter: string): [
        string,
        string
    ] {
        bjccovms5u83tl.instrumentFunction(3);
        const idx: number = input.indexOf(delimiter);
        if (idx < 0) {
            bjccovms5u83tl.instrumentBranch(3, 0, true);
            bjccovms5u83tl.instrumentRegion(3, 1);
            return [input, ''];
        }
        else {
            bjccovms5u83tl.instrumentBranch(3, 0, false);
        }
        bjccovms5u83tl.instrumentRegion(3, 2);
        return [input.substring(0, idx), input.substring(idx + 1)];
    }
    /** 去除字符串前后的 `/`。 */
    private static trimSlashes(input: string): string {
        bjccovms5u83tl.instrumentFunction(4);
        let start: number = 0;
        let end: number = input.length;
        while (start < end && input.charAt(start) === '/') {
            bjccovms5u83tl.instrumentRegion(4, 1);
            start++;
        }
        while (end > start && input.charAt(end - 1) === '/') {
            bjccovms5u83tl.instrumentRegion(4, 2);
            end--;
        }
        bjccovms5u83tl.instrumentRegion(4, 3);
        return input.substring(start, end);
    }
    /**
     * 解析 query 字符串。
     *
     * 规则: 以 `&` 拆 pair,每个 pair 在第一个 `=` 处拆 key/value,
     * key 与 value 都做 UTF-8 percent-decode,`+` 等价空格;
     * 空 key 跳过,空 value 保留;重复 key 保留首个;decode 失败的 pair 跳过。
     */
    private static parseQuery(query: string): Map<string, string> {
        bjccovms5u83tl.instrumentFunction(5);
        const out: Map<string, string> = new Map<string, string>();
        if (query.length === 0) {
            bjccovms5u83tl.instrumentBranch(5, 0, true);
            bjccovms5u83tl.instrumentRegion(5, 1);
            return out;
        }
        else {
            bjccovms5u83tl.instrumentBranch(5, 0, false);
        }
        const pairs: string[] = query.split('&');
        for (let i: number = 0; i < pairs.length; i++) {
            bjccovms5u83tl.instrumentRegion(5, 2);
            const pair: string = pairs[i];
            if (pair.length === 0) {
                bjccovms5u83tl.instrumentBranch(5, 1, true);
                bjccovms5u83tl.instrumentRegion(5, 3);
                continue;
            }
            else {
                bjccovms5u83tl.instrumentBranch(5, 1, false);
            }
            const split: [
                string,
                string
            ] = SignResultParser.splitOnce(pair, '=');
            const rawKey: string = split[0];
            const rawValue: string = split[1];
            const key: string | null = SignResultParser.decodeOrNull(rawKey);
            if (key === null || key.length === 0) {
                bjccovms5u83tl.instrumentBranch(5, 2, true);
                bjccovms5u83tl.instrumentRegion(5, 4);
                continue;
            }
            // 重复 key 保留首个
            else {
                bjccovms5u83tl.instrumentBranch(5, 2, false);
            }
            // 重复 key 保留首个
            if (out.has(key)) {
                bjccovms5u83tl.instrumentBranch(5, 3, true);
                bjccovms5u83tl.instrumentRegion(5, 5);
                continue;
            }
            else {
                bjccovms5u83tl.instrumentBranch(5, 3, false);
            }
            bjccovms5u83tl.instrumentRegion(5, 7);
            const value: string | null = SignResultParser.decodeOrNull(rawValue);
            out.set(key, value === null ? (bjccovms5u83tl.instrumentBranch(5, 4, true), '') : (bjccovms5u83tl.instrumentBranch(5, 4, false), value));
        }
        bjccovms5u83tl.instrumentRegion(5, 6);
        return out;
    }
    /**
     * UTF-8 percent-decoded; `+` 等价空格(form-urlencoded)。
     * 解码失败返回 null。
     */
    private static decodeOrNull(raw: string): string | null {
        bjccovms5u83tl.instrumentFunction(6);
        try {
            bjccovms5u83tl.instrumentRegion(6, 1);
            // 先把 `+` 替换为 `%20`(application/x-www-form-urlencoded 语义),再 decodeURIComponent
            const replaced: string = raw.replace(/\+/g, '%20');
            return decodeURIComponent(replaced);
        }
        catch (_e) {
            bjccovms5u83tl.instrumentRegion(6, 2);
            return null;
        }
    }
}
