/**
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import {Duration} from './Duration';
import {HdcClient} from './HdcClient';

export class Tracing {
  constructor(private hdcClient: HdcClient) {}

  async dump() {
    const result = await this.hdcClient.hitrace().dump();
    return new TracingResult(result);
  }

  async finish() {
    const result = await this.hdcClient.hitrace().finish();
    return new TracingResult(result);
  }
}

class TracingResult {
  constructor(private _raw: string) {}

  toString() {
    return this._raw;
  }

  private static EVENT_TRACE_BY_NAME = {
    TOUCH_END: 'EventEmitter::dispatchEvent[type][touchEnd]',
    RENDERING_START: 'H:GraphicsLoad',
  } as const;

  getLatestTimestamp(
    eventName: keyof typeof TracingResult.EVENT_TRACE_BY_NAME,
  ) {
    const timestamps = this.getTraceTimestampsByPattern(
      TracingResult.EVENT_TRACE_BY_NAME[eventName],
    );
    if (timestamps.length === 0) {
      return null;
    }
    return timestamps[timestamps.length - 1];
  }

  getTimestamps(eventName: keyof typeof TracingResult.EVENT_TRACE_BY_NAME) {
    return this.getTraceTimestampsByPattern(
      TracingResult.EVENT_TRACE_BY_NAME[eventName],
    );
  }

  private getTraceTimestampsByPattern(tracePattern: string): Duration[] {
    const escapedPattern = tracePattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    const timestampRegex = new RegExp(`(\\d+\\.\\d+):.*${escapedPattern}`);

    return this._raw
      .split('\n')
      .filter(line => line.includes(tracePattern))
      .map(line => {
        const match = line.match(timestampRegex);
        return match ? match[1] : null;
      })
      .filter((timestamp): timestamp is string => timestamp !== null)
      .map(Duration.parse);
  }
}