// Copyright (C) 2026 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 type {App} from '../../public/app';
import type {PerfettoPlugin} from '../../public/plugin';
import type {Trace} from '../../public/trace';
import m from 'mithril';
import {NUM, STR} from '../../trace_processor/query_result';
import {exists, getOrCreate} from '../../base/utils';
import StandardGroupsPlugin from '../dev.perfetto.StandardGroups';
import {TrackNode} from '../../public/workspace';
import {COUNTER_TRACK_KIND} from '../../public/track_kinds';
import {sqlNameSafe} from '../../base/string_utils';
import {CounterTrack} from '../../components/tracks/counter_track';
import {uuidv4} from '../../base/uuid';
import {CpuPage} from './cpu_page';
import {ARM_TELEMETRY_CPU_SPEC_SCHEMA} from './arm_telemetry_spec';
import type {ArmTelemetryCpuSpec} from './arm_telemetry_spec';
import {z} from 'zod';
import type {ArmTelemetrySpecManager} from './arm_telemetry_spec_manager';
import {ArmTelemetrySpecManagerImpl} from './arm_telemetry_spec_manager_impl';

type ApplicableMetricDesc = {
  name: string;
  cpus: number[];
  events: string[];
  formula: string;
};

const ARM_TELEMETRY_CPU_SPECS_SCHEMA = z.array(ARM_TELEMETRY_CPU_SPEC_SCHEMA);
const SME2_SPEC_CPUID = '0x41d8d';

function eventTableName(eventName: string): string {
  return `arm_telemetry_event_${sqlNameSafe(eventName)}`;
}

function metricTableName(metricName: string): string {
  return `arm_telemetry_metric_${sqlNameSafe(metricName)}`;
}

export default class ArmTelemetryPlugin implements PerfettoPlugin {
  static readonly id = 'com.arm.ArmTelemetry';
  static readonly description = `
    Computes Arm CPU telemetry metrics from PMU counters in the loaded trace.
    CPU specification files define the available events, metrics, and formulas
    used to create per-CPU metric tracks.
    Use the Arm CPU page to load and manage CPU specification files.
  `;
  static readonly dependencies = [StandardGroupsPlugin];
  private static specManager: ArmTelemetrySpecManager;

  static onActivate(app: App): void {
    const cpuSpecsSetting = app.settings.register<ArmTelemetryCpuSpec[]>({
      id: `${ArmTelemetryPlugin.id}.cpuSpecs`,
      name: 'Arm telemetry CPU specs',
      description: `CPU telemetry specifications used to compute Arm telemetry metrics.
        To edit, go to SUPPORT -> Arm cpu page.`,
      schema: ARM_TELEMETRY_CPU_SPECS_SCHEMA,
      defaultValue: [],
      requiresReload: true,
    });

    ArmTelemetryPlugin.specManager = new ArmTelemetrySpecManagerImpl(
      cpuSpecsSetting,
    );

    app.pages.registerPage({
      route: '/arm_cpu',
      render: () =>
        m(CpuPage, {
          specManager: ArmTelemetryPlugin.specManager,
        }),
    });
    app.sidebar.addMenuItem({
      section: 'support',
      text: 'Arm cpu',
      href: '#!/arm_cpu',
      icon: 'memory',
    });
  }

  async onTraceLoad(trace: Trace): Promise<void> {
    if (!(await this.checkRequirements(trace))) {
      return;
    }

    // Fetch the perf counters to process them in a way that suits
    // metric computation
    const countersPerCpu = await this.getPerfCountersNamePerCpu(trace);

    // Retrieve the CPUID of each CPU
    const cpuidMap = await this.getCpuIdMap(trace);

    // Create activity views required by the counters and metrics
    await this.createCpuActivityViews(trace);

    // Create all the counters view and tables
    const counters = [...new Set([...countersPerCpu.values()].flat())];
    for (const c of counters) {
      await this.createPerfCounterView(trace, c);
    }

    // Update the metric tracks if possible
    await this.updateMetricTracks(trace, cpuidMap, countersPerCpu);
  }

  // Validate that all the requirements are met to execute the plugin.
  // - At least one CPU specification has been uploaded
  // - Existence meta data asociated with the CPU table
  private async checkRequirements(ctx: Trace): Promise<boolean> {
    if (!ArmTelemetryPlugin.specManager.hasSpecs()) {
      return false;
    }

    // We need a CPU table to retrieve metrics and operate
    const q = await ctx.engine.query(`
      SELECT
        cpu,
        EXTRACT_ARG(ARG_SET_ID, 'arm_cpu_implementer') as implementer,
        EXTRACT_ARG(ARG_SET_ID, 'arm_cpu_part') as part
      FROM cpu
      WHERE implementer IS NOT NULL and part IS NOT NULL
    `);
    return q.numRows() !== 0;
  }

  // Return a map describing the perf counters associated with their CPU.
  private async getPerfCountersNamePerCpu(
    trace: Trace,
  ): Promise<Map<number, string[]>> {
    const q = await trace.engine.query(
      'SELECT name, cpu FROM perf_counter_track',
    );
    const counters: Map<number, string[]> = new Map();
    const it = q.iter({name: STR, cpu: NUM});
    for (; it.valid(); it.next()) {
      getOrCreate(counters, it.cpu, () => []).push(it.name);
    }
    return counters;
  }

  // Create views of the CPU activity (busy or idle).
  // - cpu_busy_slice: Slices when the CPU is busy
  //    - ts: timestamp marking the begining of the slice
  //    - cpu: cpu of the slice
  //    - dur: duration of the slice
  //    - utid: Thread identifier associated with the slice.
  // - cpu_idle_slice: Slices when the CPU is idle
  //    - ts: timestamp marking the begining of the slice
  //    - cpu: cpu of the slice
  //    - dur: duration of the slice
  //    - utid: Thread identifier associated with the slice.
  private async createCpuActivityViews(trace: Trace) {
    await trace.engine.query(`
        CREATE PERFETTO TABLE cpu_busy_slice AS
        WITH whole_counter_slice(ts, dur) AS
          (VALUES ((SELECT ts FROM counter ORDER BY ts LIMIT 1),
            (SELECT ts FROM counter ORDER BY ts DESC LIMIT 1) - (SELECT ts FROM counter ORDER BY ts LIMIT 1))
          )
        SELECT cpu,ts,dur,utid
        FROM sched_slice
        WHERE utid != 0
        UNION
        -- Add placeholder if the sched_slice is not available
        SELECT DISTINCT cpu, ts, dur, NULL AS utid
        FROM perf_counter_track
          JOIN whole_counter_slice
        WHERE NOT EXISTS (SELECT * FROM sched_slice)
        ORDER BY cpu,ts;
          `);

    await trace.engine.query(`
            CREATE PERFETTO TABLE cpu_idle_slice AS
            SELECT
              ts,
              cpu,
              0 as value,
              dur,
              utid
            FROM sched_slice
            WHERE utid = 0
            ORDER BY cpu,ts;
          `);
  }

  // Create the view in the DB of the counter named in input.
  // The views is named after the arm_telemetry_event_{counterName}
  //  and contains the following fields:
  // - ts: The timestamp of the sample
  // - cpu: The cpu of the sample
  // - {counter}_counter: The accumulated value of the counter
  // - {counter}: The delta between the counter and the one from the next sample
  // - dur: The duration of the sample
  // The view is also SPAN_JOIN using the cpu_busy_slice table.
  // As a result, no sample happens while the CPU is idle.
  private async createPerfCounterView(trace: Trace, counterName: string) {
    const tableName = eventTableName(counterName);

    await trace.engine.query(`
        DROP VIEW IF EXISTS __raw_${tableName};
        CREATE VIEW __raw_${tableName} AS
        SELECT
          ts,
          cpu,
          value AS ${counterName}_counter,
          LEAD(value, 1, value) OVER (PARTITION BY cpu ORDER BY ts) - value AS ${counterName},
          LEAD(ts, 1, ts ) OVER (PARTITION BY cpu ORDER BY ts ) - ts AS dur
        FROM counter
          JOIN perf_counter_track
            ON perf_counter_track.id = counter.track_id
        WHERE
          name like '${counterName}';

        DROP TABLE IF EXISTS __virtual_${tableName};
        CREATE VIRTUAL TABLE __virtual_${tableName} USING SPAN_JOIN(
          __raw_${tableName} PARTITIONED cpu,
          cpu_busy_slice PARTITIONED cpu
        );

        DROP TABLE IF EXISTS ${tableName};
        CREATE TABLE ${tableName} AS
        SELECT *
        FROM __virtual_${tableName}
        ORDER BY cpu,ts;
      `);
  }

  // Update metric tracks.
  //
  // This function is called once when the trace is loaded. Specs are expected
  // to be registered before trace load; changing specs requires a trace reload.
  private async updateMetricTracks(
    trace: Trace,
    cpuidMap: Map<number, string>,
    countersPerCpu: Map<number, string[]>,
  ): Promise<void> {
    const metrics = this.getComputableMetrics(cpuidMap, countersPerCpu);
    const metricEntries = Object.entries(metrics);
    if (metricEntries.length === 0) {
      return;
    }

    await this.createMetrics(trace, metrics, [...cpuidMap.keys()]);

    // Retrieve the hardware node in the workspace
    const hardwareGroup = trace.plugins
      .getPlugin(StandardGroupsPlugin)
      .getOrCreateStandardGroup(trace.workspaces.currentWorkspace, 'HARDWARE');

    // Create and attach the main telemetry node
    const telemetryRootNode = new TrackNode({name: 'CPU metrics'});
    hardwareGroup.addChildInOrder(telemetryRootNode);

    // Iterate over all the metrics to create tracks.
    for (const [metricName, desc] of metricEntries) {
      // retrieve CPU this metric applies to
      const cpus = desc
        .map((e) => e.cpus)
        .flat()
        .sort();

      for (const c of cpus) {
        const tableName = metricTableName(metricName);
        // Note: It is not possible to deregister track explicitly.
        // For this reason it is important to have a UID in the URI.
        const uri = `/arm_telemetry/${metricName}_${c}#${uuidv4()}`;
        const track = new CounterTrack({
          trace,
          uri,
          sqlSource: `select * from ${tableName} where cpu = ${c}`,
        });
        trace.tracks.registerTrack({
          uri,
          tags: {
            kind: COUNTER_TRACK_KIND,
            cpu: c,
            groupName: `arm_telemetry/${metricName}`,
          },
          renderer: track,
        });

        telemetryRootNode.addChildInOrder(
          new TrackNode({uri, name: `${metricName} for CPU ${c}`}),
        );
      }
    }
  }

  private getComputableMetrics(
    cpuids: Map<number, string>,
    cpuCountersMap: Map<number, string[]>,
  ) {
    const telemetrySpecManager = ArmTelemetryPlugin.specManager;

    // Align cpuids to process the counter available
    cpuids = new Map<number, string>(
      [...cpuids.entries()].filter(([k, _]) => cpuCountersMap.has(k)),
    );

    // Resolve the generic/co-processor spec if registered
    const registered = telemetrySpecManager.registeredCpuids();
    const genericSpec = registered.includes(SME2_SPEC_CPUID)
      ? telemetrySpecManager.getCpuDesc(SME2_SPEC_CPUID)
      : undefined;

    // Build the list of specs per CPU: CPUID-specific + generic (if present)
    const cpuSpecs = new Map<number, ArmTelemetryCpuSpec[]>();
    for (const [cpu, cpuid] of cpuids.entries()) {
      const specs: ArmTelemetryCpuSpec[] = [];
      if (registered.includes(cpuid)) {
        specs.push(telemetrySpecManager.getCpuDesc(cpuid));
      }
      if (genericSpec) {
        specs.push(genericSpec);
      }
      if (specs.length > 0) {
        cpuSpecs.set(cpu, specs);
      }
    }

    // For each cpu find applicable metrics based on its available counters
    const allApplicableMetrics: ApplicableMetricDesc[] = [];
    for (const [cpu, specs] of cpuSpecs.entries()) {
      const counters = cpuCountersMap.get(cpu)!;
      for (const spec of specs) {
        for (const [name, metric] of Object.entries(spec.metrics)) {
          if (metric.events.every((e) => counters.includes(e))) {
            allApplicableMetrics.push({
              name,
              cpus: [cpu],
              formula: metric.formula,
              events: metric.events,
            });
          }
        }
      }
    }

    // Merge metrics together
    const applicableMetrics: {[name: string]: ApplicableMetricDesc[]} = {};
    allApplicableMetrics.forEach((m) => {
      const name = m.name;
      const entry = applicableMetrics[name];
      if (exists(entry)) {
        const found = entry.find((candidate) => {
          return (
            m.formula === candidate.formula &&
            m.events.every((e) => candidate.events.includes(e))
          );
        });

        if (exists(found)) {
          const cpu = m.cpus[0];
          if (!found.cpus.includes(cpu)) {
            found.cpus.push(cpu);
          }
        } else {
          entry.push(m);
        }
      } else {
        applicableMetrics[name] = [m];
      }
    });

    return applicableMetrics;
  }

  // Retrieve the cpuid for each CPU
  private async getCpuIdMap(trace: Trace): Promise<Map<number, string>> {
    const result = new Map<number, string>();

    const q = await trace.engine.query(`
      SELECT
        cpu,
        EXTRACT_ARG(ARG_SET_ID, "arm_cpu_implementer") as implementer,
        EXTRACT_ARG(ARG_SET_ID, "arm_cpu_part") as part
      FROM cpu
      WHERE implementer IS NOT NULL and part IS NOT NULL
    `);

    const iter = q.iter({
      cpu: NUM,
      implementer: NUM,
      part: NUM,
    });
    for (; iter.valid(); iter.next()) {
      const cpuid = `0x${iter.implementer.toString(16)}${iter.part.toString(16)}`;
      result.set(iter.cpu, cpuid);
    }

    return result;
  }

  // Compute a given metric from its formula. The metric is created as a
  // table in the database. The name of the table arm_telemetry_metric_{metricName}.
  // The table contains the following fields:
  //   - ts: timestamp of the sample
  //   - cpu: cpu of the sample
  //   - dur: duration of the sampling
  //   - value: value computed from the metric formula
  //   - utid: Thread associated with the sample.
  private async createMetrics(
    trace: Trace,
    metricsPerName: {[name: string]: ApplicableMetricDesc[]},
    applicableCpus: number[],
  ) {
    const idleSegment = `
      SELECT
        ts,
        cpu,
        dur,
        0 AS value,
        0 AS utid
      FROM cpu_idle_slice
    `;

    for (const [metricName, metrics] of Object.entries(metricsPerName)) {
      const tableName = metricTableName(metricName);

      // Implementation notes:
      // - If all the CPUs share the same metric definition, just select the
      //   various counters of the metric then use the formula to compute the metric.
      // - If not all the CPUs share the same metric definition then operate at that
      //   metric definition level for each definition and do a UNION.
      // - All the metrics are unioned with the cpu_idle_slice to let the metric drop
      //   to 0 when the CPU is idle.

      // Optimize query if it is applicable to all the CPUS
      if (
        metrics.length == 1 &&
        metrics[0].cpus.length == applicableCpus.length &&
        metrics[0].cpus.every((c) => applicableCpus.includes(c))
      ) {
        const metric = metrics[0];
        const firstTable = eventTableName(metric.events[0]);
        const fromClause = metric.events.slice(1).reduce((acc, counter) => {
          const counterTable = eventTableName(counter);
          return (
            acc +
            ` LEFT JOIN ${counterTable}` +
            ` ON ${firstTable}.ROWID = ${counterTable}.ROWID`
          );
        }, firstTable);

        await trace.engine.query(`
            DROP TABLE IF EXISTS ${tableName};
            CREATE TABLE ${tableName} AS
            SELECT
              ${firstTable}.ts AS ts,
              ${firstTable}.cpu AS cpu,
              ${firstTable}.dur AS dur,
              ifnull(${metric.formula},0) AS value,
              ${firstTable}.utid AS utid
            FROM ${fromClause}
            UNION ${idleSegment}
            ORDER BY ts;
          `);
      } else {
        await trace.engine.query(`
          DROP TABLE IF EXISTS ${tableName};
          CREATE TABLE ${tableName} AS
          ${metrics.reduce<string>((acc, metric) => {
            const firstTable = eventTableName(metric.events[0]);
            const fromClause = metric.events.slice(1).reduce((acc, counter) => {
              const counterTable = eventTableName(counter);
              return (
                acc +
                ` LEFT JOIN ${counterTable}` +
                ` ON ${firstTable}.ROWID = ${counterTable}.ROWID`
              );
            }, firstTable);
            const whereClause = metric.cpus
              .slice(1)
              .reduce(
                (acc, cpu) => acc + ` OR ${firstTable}.cpu = ${cpu}`,
                `${firstTable}.cpu = ${metric.cpus[0]}`,
              );
            return (
              acc +
              `
              SELECT
                ${firstTable}.ts AS ts,
                ${firstTable}.cpu AS cpu,
                ${firstTable}.dur AS dur,
                ifnull(${metric.formula},0) AS value,
                ${firstTable}.utid AS utid
              FROM ${fromClause}
              WHERE ${whereClause}
              UNION`
            );
          }, '')}
          ${idleSegment}
          ORDER BY ts;
        `);
      }
    }
  }
}
