import hiAppEvent from "@ohos.hiviewdfx.hiAppEvent";
import { AIOCrashLogger } from './utils/AIOCrashLogger';
import { AIOCrashLogContentBuilder } from "./AIOCrashLogContentBuilder";
import { AIOCrashTimeUtils } from './utils/AIOCrashTimeUtils';
import { AIOCrashApi } from './AIOCrashApi';
import { AIOCrashDeviceInfo } from './utils/AIOCrashDeviceInfo';
const TAG = 'AIOCrashWatcher';
const WATCHER_NAME = 'alivc_aio_crash_watcher';
const EVENT_CONTEXT_KEY = "alivc_aio_crash_event_context";
export class AIOCrashWatcher {
    static Setup(u5, v5, w5, x5, y5, z5) {
        if (AIOCrashWatcher.HasSetup) {
            return;
        }
        AIOCrashWatcher.HasSetup = true;
        AIOCrashApi.RequestUrl = y5;
        AIOCrashWatcher.UserId = x5;
        AIOCrashWatcher.AppId = u5;
        AIOCrashWatcher.SdkVersion = v5;
        AIOCrashWatcher.SdkBuildNumber = w5;
        AIOCrashLogger.info(TAG, `Setup crash watcher with appId(${u5}), sdkVersion(${v5}), sdkBuildNumber(${w5})`);
        hiAppEvent.addWatcher({
            name: WATCHER_NAME,
            appEventFilters: [
                {
                    domain: hiAppEvent.domain.OS,
                    names: [hiAppEvent.event.APP_CRASH, hiAppEvent.event.APP_FREEZE]
                }
            ],
            onReceive: (a6, b6) => {
                AIOCrashLogger.debug(TAG, `onReceive: domain=${a6}`);
                for (const c6 of b6) {
                    AIOCrashLogger.debug(TAG, `eventName=${c6.name}`);
                    for (const d6 of c6.appEventInfos) {
                        AIOCrashLogger.debug(TAG, `eventInfo domain=${d6.domain}, name=${d6.name}, type=${d6.eventType}`);
                        AIOCrashWatcher.process(d6, z5)
                            .catch((f6) => {
                            AIOCrashLogger.error(TAG, `report event error: ${f6}`);
                        });
                    }
                }
            }
        });
    }
    static SetContext(o5, p5) {
        AIOCrashWatcher.EventContext = JSON.stringify({
            'modules': o5,
            'params': p5
        });
        const q5 = {
            'alivc_aio_crash_event_context': AIOCrashWatcher.EventContext
        };
        hiAppEvent.setEventParam(q5, hiAppEvent.domain.OS, hiAppEvent.event.APP_CRASH).then(() => {
            AIOCrashLogger.info(TAG, 'set event param success');
        }).catch((t5) => {
            AIOCrashLogger.error(TAG, `set event param error with code(${t5.code}), msg(${t5.message})`);
        });
    }
    static async process(s4, t4) {
        const u4 = s4.params;
        const v4 = u4[EVENT_CONTEXT_KEY];
        if (v4 === undefined || v4.length === 0) {
            return;
        }
        const w4 = JSON.parse(v4);
        const x4 = w4['modules'];
        if (x4 === undefined || x4.length === 0) {
            return;
        }
        const y4 = u4["foreground"] ? 'fg' : 'bg';
        const z4 = AIOCrashWatcher.createLogContentBuilder(s4);
        z4.setUserId(AIOCrashWatcher.UserId);
        z4.setProcessId(u4['pid']);
        z4.setProcessName(u4['bundle_name']);
        z4.setThreadId(AIOCrashWatcher.getThreadId(s4));
        z4.setForeground(y4);
        z4.setVersion(AIOCrashWatcher.SdkVersion);
        z4.setBuildNumber(AIOCrashWatcher.SdkBuildNumber);
        z4.setCrashTime(AIOCrashTimeUtils.formatTimestamp(u4['time']));
        z4.addParam("wk_crash_ohos_uid", u4['uid']);
        z4.setReportUUID(u4['uuid']);
        if (z4.isJSCrash()) {
            z4.setExceptionName(u4['exception']['name']);
            z4.setExceptionMessage(u4['exception']['message']);
            const n5 = u4['exception']['stack'].replace(/\\n/g, '\n');
            z4.setStackTrace(n5);
        }
        else if (z4.isNativeCrash()) {
            z4.setThreadName(u4['exception']['thread_name']);
            z4.setExceptionMessage(u4['exception']['message']);
            z4.setSignal(u4['exception']['signal']['signo']);
            z4.setSignalCode(u4['exception']['signal']['code']);
            z4.setStackTraceByFrames(u4['exception']['frames']);
            z4.addOtherThreads(u4['threads']);
        }
        else if (z4.isAppFreeze()) {
            z4.setExceptionName(u4['exception']['name']);
            z4.setExceptionMessage(u4['exception']['message']);
            z4.addOtherThreads(u4['threads']);
            z4.setEventHandlerInfo(u4['event_handler']);
            z4.setEventHandler3sSize(u4['event_handler_size_3s']);
            z4.setEventHandler6sSize(u4['event_handler_size_6s']);
            z4.setPeerBinder(u4['peer_binder']);
            z4.setMemory(u4['memory']);
        }
        const a5 = z4.matchModules(x4);
        if (a5 === undefined) {
            return;
        }
        const b5 = new Map();
        const c5 = w4['params'];
        Object.keys(c5).forEach(m5 => {
            b5.set(m5, String(c5[m5]));
        });
        const d5 = new Map([
            ['dump_from', 'ts'],
            ['crash_time', z4.getCrashTime()],
            ['log_name', z4.buildReportName()],
            ['crash_type', z4.getLogType()],
            ['app_status', z4.getForeground()],
            ['appPkgName', AIOCrashDeviceInfo.getApplicationBundleName()],
        ]);
        d5.forEach((k5, l5) => {
            b5.set(l5, k5);
        });
        a5.toMap().forEach((i5, j5) => {
            b5.set(j5, i5);
        });
        z4.addCustomParams(b5);
        z4.setHiLog(u4['hilog'].join('\n'));
        const e5 = z4.buildLog();
        AIOCrashLogger.info(TAG, `${e5}`);
        AIOCrashApi.reportExceptionFile(z4.buildReportName(), e5);
        t4(b5);
    }
    static createLogContentBuilder(p4) {
        const q4 = AIOCrashWatcher.AppId;
        const r4 = p4.params['crash_type'];
        if ("NativeCrash" === r4) {
            return AIOCrashLogContentBuilder.createNativeCrash(q4);
        }
        else if ("JsError" === r4) {
            return AIOCrashLogContentBuilder.createJSCrash(q4);
        }
        else {
            return AIOCrashLogContentBuilder.createAppFreeze(q4);
        }
    }
    static getThreadId(o4) {
        if ("NativeCrash" === o4.params['crash_type']) {
            return o4.params['exception']['tid'];
        }
        return '-1';
    }
}
AIOCrashWatcher.HasSetup = false;
AIOCrashWatcher.UserId = '';
AIOCrashWatcher.AppId = '';
AIOCrashWatcher.SdkVersion = '';
AIOCrashWatcher.SdkBuildNumber = '';
AIOCrashWatcher.EventContext = '';
