// 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 {uuidv4} from '../base/uuid';
import {Actions, DeferredAction} from '../common/actions';
import {SCROLLING_TRACK_GROUP} from '../common/state';
import {globals} from './globals';
import {Engine, PrimaryTrackSortKey} from '../public';
import {DebugTrackV2Config} from '../core_plugins/debug/slice_track';

export const ARG_PREFIX = 'arg_';
export const DEBUG_SLICE_TRACK_URI = 'perfetto.DebugSlices';
export const DEBUG_COUNTER_TRACK_URI = 'perfetto.DebugCounter';

// Names of the columns of the underlying view to be used as
// ts / dur / name / pivot.
export interface SliceColumns {
  ts: string;
  dur: string;
  name: string;
  pivot?: string;
}

export interface DebugTrackV2CreateConfig {
  pinned?: boolean; // default true
  closeable?: boolean; // default true
}

let debugTrackCount = 0;

export interface SqlDataSource {
  // SQL source selecting the necessary data.
  sqlSource: string;

  // Optional: Rename columns from the query result.
  // If omitted, original column names from the query are used instead.
  // The caller is responsible for ensuring that the number of items in this
  // list matches the number of columns returned by sqlSource.
  columns?: string[];
}

// Creates actions to add a debug track. The actions must be dispatched to
// have an effect. Use this variant if you want to create many tracks at
// once or want to tweak the actions once produced. Otherwise, use
// addDebugSliceTrack().
export async function createDebugSliceTrackActions(
  _engine: Engine,
  data: SqlDataSource,
  trackName: string,
  sliceColumns: SliceColumns,
  argColumns: string[],
  config?: DebugTrackV2CreateConfig,
): Promise<DeferredAction<{}>[]> {
  const debugTrackId = ++debugTrackCount;
  const closeable = config?.closeable ?? true;
  const trackKey = uuidv4();

  const trackConfig: DebugTrackV2Config = {
    data,
    columns: sliceColumns,
    argColumns,
  };

  const actions: DeferredAction<{}>[] = [
    Actions.addTrack({
      key: trackKey,
      name: trackName.trim() || `Debug Track ${debugTrackId}`,
      uri: DEBUG_SLICE_TRACK_URI,
      trackSortKey: PrimaryTrackSortKey.DEBUG_TRACK,
      trackGroup: SCROLLING_TRACK_GROUP,
      params: trackConfig,
      closeable,
    }),
  ];
  if (config?.pinned ?? true) {
    actions.push(Actions.toggleTrackPinned({trackKey}));
  }
  return actions;
}

export async function addPivotDebugSliceTracks(
  engine: Engine,
  data: SqlDataSource,
  trackName: string,
  sliceColumns: SliceColumns,
  argColumns: string[],
  config?: DebugTrackV2CreateConfig,
) {
  if (sliceColumns.pivot) {
    // Get distinct values to group by
    const pivotValues = await engine.query(`
      with all_vals as (${data.sqlSource})
      select DISTINCT ${sliceColumns.pivot} from all_vals;`);

    const iter = pivotValues.iter({});

    for (; iter.valid(); iter.next()) {
      const pivotDataSource: SqlDataSource = {
        sqlSource: `select * from
        (${data.sqlSource})
        where ${sliceColumns.pivot} = '${iter.get(sliceColumns.pivot)}'`,
      };

      const actions = await createDebugSliceTrackActions(
        engine,
        pivotDataSource,
        `${trackName.trim() || 'Pivot Track'}: ${iter.get(sliceColumns.pivot)}`,
        sliceColumns,
        argColumns,
        config,
      );

      globals.dispatchMultiple(actions);
    }
  }
}

// Adds a debug track immediately. Use createDebugSliceTrackActions() if you
// want to create many tracks at once.
export async function addDebugSliceTrack(
  engine: Engine,
  data: SqlDataSource,
  trackName: string,
  sliceColumns: SliceColumns,
  argColumns: string[],
  config?: DebugTrackV2CreateConfig,
) {
  const actions = await createDebugSliceTrackActions(
    engine,
    data,
    trackName,
    sliceColumns,
    argColumns,
    config,
  );
  globals.dispatchMultiple(actions);
}

// Names of the columns of the underlying view to be used as ts / dur / name.
export interface CounterColumns {
  ts: string;
  value: string;
}

export interface CounterDebugTrackConfig {
  data: SqlDataSource;
  columns: CounterColumns;
}

export interface CounterDebugTrackCreateConfig {
  pinned?: boolean; // default true
  closeable?: boolean; // default true
}

// Creates actions to add a debug track. The actions must be dispatched to
// have an effect. Use this variant if you want to create many tracks at
// once or want to tweak the actions once produced. Otherwise, use
// addDebugCounterTrack().
export async function createDebugCounterTrackActions(
  data: SqlDataSource,
  trackName: string,
  columns: CounterColumns,
  config?: CounterDebugTrackCreateConfig,
) {
  // To prepare displaying the provided data as a track, materialize it and
  // compute depths.
  const debugTrackId = ++debugTrackCount;

  const closeable = config?.closeable ?? true;
  const params: CounterDebugTrackConfig = {
    data,
    columns,
  };

  const trackKey = uuidv4();
  const actions: DeferredAction<{}>[] = [
    Actions.addTrack({
      key: trackKey,
      uri: DEBUG_COUNTER_TRACK_URI,
      name: trackName.trim() || `Debug Track ${debugTrackId}`,
      trackSortKey: PrimaryTrackSortKey.DEBUG_TRACK,
      trackGroup: SCROLLING_TRACK_GROUP,
      params,
      closeable,
    }),
  ];
  if (config?.pinned ?? true) {
    actions.push(Actions.toggleTrackPinned({trackKey}));
  }
  return actions;
}

// Adds a debug track immediately. Use createDebugCounterTrackActions() if you
// want to create many tracks at once.
export async function addDebugCounterTrack(
  data: SqlDataSource,
  trackName: string,
  columns: CounterColumns,
  config?: CounterDebugTrackCreateConfig,
) {
  const actions = await createDebugCounterTrackActions(
    data,
    trackName,
    columns,
    config,
  );
  globals.dispatchMultiple(actions);
}
