// Copyright (C) 2024 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import {Trace} from '../../public/trace';
import {PerfettoPlugin} from '../../public/plugin';
import {METRIC_HANDLERS} from './handlers/handlerRegistry';
import {MetricData, MetricHandlerMatch} from './handlers/metricUtils';
import {PLUGIN_ID} from './pluginId';

const JANK_CUJ_QUERY_PRECONDITIONS = `
  SELECT RUN_METRIC('android/android_blocking_calls_cuj_metric.sql');
`;

function getMetricsFromHash(): string[] {
  const metricVal = location.hash;
  const regex = new RegExp(`${PLUGIN_ID}:metrics=(.*)`);
  const match = metricVal.match(regex);
  if (match === null) {
    return [];
  }
  const capturedString = match[1];
  let metricList: string[] = [];
  if (capturedString.includes('--')) {
    metricList = capturedString.split('--');
  } else {
    metricList = [capturedString];
  }
  return metricList.map((metric) => decodeURIComponent(metric));
}

let metrics: string[];

/**
 * Plugin that adds and pins the debug track for the metric passed
 * For more context -
 * This plugin reads the names of regressed metrics from the url upon loading
 * It then checks the metric names against some handlers and if they
 * match it accordingly adds the debug tracks for them
 * This way when comparing two different perfetto traces before and after
 * the regression, the user will not have to manually search for the
 * slices related to the regressed metric
 */
export default class implements PerfettoPlugin {
  static readonly id = PLUGIN_ID;

  static onActivate(): void {
    metrics = getMetricsFromHash();
  }

  async onTraceLoad(ctx: Trace) {
    ctx.addEventListener('traceready', () => {
      ctx.commands.registerCommand({
        id: 'dev.perfetto.PinAndroidPerfMetrics#PinAndroidPerfMetrics',
        name: 'Add and Pin: Jank Metric Slice',
        callback: async (metric) => {
          metric = prompt('Metrics names (separated by comma)', '');
          if (metric === null) return;
          const metricList = metric.split(',');
          this.callHandlers(metricList, ctx);
        },
      });
      if (metrics.length !== 0) {
        this.callHandlers(metrics, ctx);
      }
    });
  }

  private async callHandlers(metricsList: string[], ctx: Trace) {
    // List of metrics that actually match some handler
    const metricsToShow: MetricHandlerMatch[] =
      this.getMetricsToShow(metricsList);

    if (metricsToShow.length === 0) {
      return;
    }

    await ctx.engine.query(JANK_CUJ_QUERY_PRECONDITIONS);
    for (const {metricData, metricHandler} of metricsToShow) {
      metricHandler.addMetricTrack(metricData, ctx);
    }
  }

  private getMetricsToShow(metricList: string[]): MetricHandlerMatch[] {
    const sortedMetricList = [...metricList].sort();
    const validMetrics: MetricHandlerMatch[] = [];
    const alreadyMatchedMetricData: Set<string> = new Set();
    for (const metric of sortedMetricList) {
      for (const metricHandler of METRIC_HANDLERS) {
        const metricData = metricHandler.match(metric);
        if (!metricData) continue;
        const jsonMetricData = this.metricDataToJson(metricData);
        if (!alreadyMatchedMetricData.has(jsonMetricData)) {
          alreadyMatchedMetricData.add(jsonMetricData);
          validMetrics.push({
            metricData: metricData,
            metricHandler: metricHandler,
          });
        }
      }
    }
    return validMetrics;
  }

  private metricDataToJson(metricData: MetricData): string {
    // Used to have a deterministic keys order.
    return JSON.stringify(metricData, Object.keys(metricData).sort());
  }
}
