// Copyright (C) 2023 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 {
  Plugin,
  PluginContext,
  PluginContextTrace,
  PluginDescriptor,
} from '../../public';
import {addDebugSliceTrack} from '../../public';
import {runQuery} from '../../common/queries';

const PERF_TRACE_COUNTERS_PRECONDITION = `
  SELECT
    str_value
  FROM metadata
  WHERE
    name = 'trace_config_pbtxt'
    AND str_value GLOB '*ftrace_events: "perf_trace_counters/sched_switch_with_ctrs"*'
`;

class AndroidPerfTraceCounters implements Plugin {
  onActivate(_: PluginContext): void {}

  async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
    const resp = await runQuery(PERF_TRACE_COUNTERS_PRECONDITION, ctx.engine);
    if (resp.totalRowCount === 0) return;
    ctx.registerCommand({
      id: 'dev.perfetto.AndroidPerfTraceCounters#ThreadRuntimeIPC',
      name: 'Add a track to show a thread runtime ipc',
      callback: async (tid) => {
        if (tid === undefined) {
          tid = prompt('Enter a thread tid', '');
          if (tid === null) return;
        }
        const sqlPrefix = `
          WITH
            sched_switch_ipc AS (
              SELECT
                ts,
                EXTRACT_ARG(arg_set_id, 'prev_pid') AS tid,
                EXTRACT_ARG(arg_set_id, 'prev_comm') AS thread_name,
                EXTRACT_ARG(arg_set_id, 'inst') / (EXTRACT_ARG(arg_set_id, 'cyc') * 1.0) AS ipc,
                EXTRACT_ARG(arg_set_id, 'inst') AS instruction,
                EXTRACT_ARG(arg_set_id, 'cyc') AS cycle,
                EXTRACT_ARG(arg_set_id, 'stallbm') AS stall_backend_mem,
                EXTRACT_ARG(arg_set_id, 'l3dm') AS l3_cache_miss
              FROM ftrace_event
              WHERE name = 'sched_switch_with_ctrs' AND tid = ${tid}
            ),
            target_thread_sched_slice AS (
              SELECT s.*, t.tid, t.name FROM sched s LEFT JOIN thread t USING (utid)
                WHERE t.tid = ${tid}
            ),
            target_thread_ipc_slice AS (
              SELECT
                (
                  SELECT
                    ts
                  FROM target_thread_sched_slice ts
                  WHERE ts.tid = ssi.tid AND ts.ts < ssi.ts
                  ORDER BY ts.ts DESC
                  LIMIT 1
                ) AS ts,
                (
                  SELECT
                    dur
                  FROM target_thread_sched_slice ts
                  WHERE ts.tid = ssi.tid AND ts.ts < ssi.ts
                  ORDER BY ts.ts DESC
                  LIMIT 1
                ) AS dur,
                ssi.ipc,
                ssi.instruction,
                ssi.cycle,
                ssi.stall_backend_mem,
                ssi.l3_cache_miss
              FROM sched_switch_ipc ssi
            )
        `;

        await addDebugSliceTrack(
          ctx.engine,
          {
            sqlSource: sqlPrefix + `
              SELECT * FROM target_thread_ipc_slice WHERE ts IS NOT NULL`,
          },
          'Rutime IPC:' + tid,
          {ts: 'ts', dur: 'dur', name: 'ipc'},
          ['instruction', 'cycle', 'stall_backend_mem', 'l3_cache_miss'],
        );
        ctx.tabs.openQuery(
          sqlPrefix + `
            SELECT
              (sum(instruction) * 1.0 / sum(cycle)*1.0) AS avg_ipc,
              sum(dur)/1e6 as total_runtime_ms,
              sum(instruction) AS total_instructions,
              sum(cycle) AS total_cycles,
              sum(stall_backend_mem) as total_stall_backend_mem,
              sum(l3_cache_miss) as total_l3_cache_miss
            FROM target_thread_ipc_slice WHERE ts IS NOT NULL`,
          'target thread ipc statistic',
        );
      },
    });
  }
}

export const plugin: PluginDescriptor = {
  pluginId: 'dev.perfetto.AndroidPerfTraceCounters',
  plugin: AndroidPerfTraceCounters,
};
