// Copyright (C) 2022 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 m from 'mithril';

import {Hotkey} from '../base/hotkeys';
import {duration, time} from '../base/time';
import {ColorScheme} from '../common/colorizer';
import {Store} from '../frontend/store';
import {EngineProxy} from '../trace_processor/engine';

export {createStore, Store} from '../frontend/store';
export {EngineProxy} from '../trace_processor/engine';
export {
  LONG,
  LONG_NULL,
  NUM,
  NUM_NULL,
  STR,
  STR_NULL,
} from '../trace_processor/query_result';

export interface Slice {
  // These properties are updated only once per query result when the Slice
  // object is created and don't change afterwards.
  readonly id: number;
  readonly startNsQ: time;
  readonly endNsQ: time;
  readonly durNsQ: duration;
  readonly ts: time;
  readonly dur: duration;
  readonly depth: number;
  readonly flags: number;

  // Each slice can represent some extra numerical information by rendering a
  // portion of the slice with a lighter tint.
  // |fillRatio\ describes the ratio of the normal area to the tinted area
  // width of the slice, normalized between 0.0 -> 1.0.
  // 0.0 means the whole slice is tinted.
  // 1.0 means none of the slice is tinted.
  // E.g. If |fillRatio| = 0.65 the slice will be rendered like this:
  // [############|*******]
  // ^------------^-------^
  //     Normal     Light
  readonly fillRatio: number;

  // These can be changed by the Impl.
  title: string;
  subTitle: string;
  colorScheme: ColorScheme;
  isHighlighted: boolean;
}

export interface Command {
  // A unique id for this command.
  id: string;
  // A human-friendly name for this command.
  name: string;
  // Callback is called when the command is invoked.
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  callback: (...args: any[]) => any;
  // Default hotkey for this command.
  // Note: this is just the default and may be changed by the user.
  // Examples:
  // - 'P'
  // - 'Shift+P'
  // - '!Mod+Shift+P'
  // See hotkeys.ts for guidance on hotkey syntax.
  defaultHotkey?: Hotkey;
}

export interface MetricVisualisation {
  // The name of the metric e.g. 'android_camera'
  metric: string;

  // A vega or vega-lite visualisation spec.
  // The data from the metric under path will be exposed as a
  // datasource named "metric" in Vega(-Lite)
  spec: string;

  // A path index into the metric.
  // For example if the metric returns the folowing protobuf:
  // {
  //   foo {
  //     bar {
  //       baz: { name: "a" }
  //       baz: { name: "b" }
  //       baz: { name: "c" }
  //     }
  //   }
  // }
  // That becomes the following json:
  // { "foo": { "bar": { "baz": [
  //  {"name": "a"},
  //  {"name": "b"},
  //  {"name": "c"},
  // ]}}}
  // And given path = ["foo", "bar", "baz"]
  // We extract:
  // [ {"name": "a"}, {"name": "b"}, {"name": "c"} ]
  // And pass that to the vega(-lite) visualisation.
  path: string[];
}

// This interface defines a context for a plugin, which is an object passed to
// most hooks within the plugin. It should be used to interact with Perfetto.
export interface PluginContext {
  // The unique ID for this plugin.
  readonly pluginId: string;

  // Register command against this plugin context.
  registerCommand(command: Command): void;

  // Retrieve a list of all commands.
  commands: Command[];

  // Run a command, optionally passing some args.
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  runCommand(id: string, ...args: any[]): any;

  // Control of the sidebar.
  sidebar: {
    // Show the sidebar.
    show(): void;

    // Hide the sidebar.
    hide(): void;

    // Returns true if the sidebar is visible.
    isVisible(): boolean;
  };
}

export type Migrate<State> = (init: unknown) => State;

export interface TrackContext {
  // This track's key, used for making selections et al.
  trackKey: string;

  // Set of params passed in when the track was created.
  params: unknown;

  // Creates a new store overlaying the track instance's state object.
  // A migrate function must be passed to convert any existing state to a
  // compatible format.
  // When opening a fresh trace, the value of |init| will be undefined, and
  // state should be updated to an appropriate default value.
  // When loading a permalink, the value of |init| will be whatever was saved
  // when the permalink was shared, which might be from an old version of this
  // track.
  mountStore<State>(migrate: Migrate<State>): Store<State>;
}

export interface SliceRect {
  left: number;
  width: number;
  top: number;
  height: number;
  visible: boolean;
}

export interface Track {
  onCreate(ctx: TrackContext): void;
  render(ctx: CanvasRenderingContext2D): void;
  onFullRedraw(): void;
  getSliceRect(tStart: time, tEnd: time, depth: number): SliceRect|undefined;
  getHeight(): number;
  getTrackShellButtons(): m.Children;
  onMouseMove(position: {x: number, y: number}): void;
  onMouseClick(position: {x: number, y: number}): boolean;
  onMouseOut(): void;
  onDestroy(): void;
}

// A definition of a track, including a renderer implementation and metadata.
export interface TrackDescriptor {
  // A unique identifier for this track.
  uri: string;

  // A factory function returning the track object.
  track: (ctx: TrackContext) => Track;

  // The track "kind", used by various subsystems e.g. aggregation controllers.
  // This is where "XXX_TRACK_KIND" values should be placed.
  // TODO(stevegolton): This will be deprecated once we handle group selections
  // in a more generic way - i.e. EventSet.
  kind?: string;

  // Optional: list of track IDs represented by this trace.
  // This list is used for participation in track indexing by track ID.
  // This index is used by various subsystems to find links between tracks based
  // on the track IDs used by trace processor.
  trackIds?: number[];

  // Optional: The CPU number associated with this track.
  cpu?: number;

  // Optional: The UTID associated with this track.
  utid?: number;

  // Optional: The UPID associated with this track.
  upid?: number;

  // Optional: A list of tags used for sorting, grouping and "chips".
  tags?: TrackTags;
}

// Tracks within track groups (usually corresponding to processes) are sorted.
// As we want to group all tracks related to a given thread together, we use
// two keys:
// - Primary key corresponds to a priority of a track block (all tracks related
//   to a given thread or a single track if it's not thread-associated).
// - Secondary key corresponds to a priority of a given thread-associated track
//   within its thread track block.
// Each track will have a sort key, which either a primary sort key
// (for non-thread tracks) or a tid and secondary sort key (mapping of tid to
// primary sort key is done independently).
export enum PrimaryTrackSortKey {
  DEBUG_TRACK,
  NULL_TRACK,
  PROCESS_SCHEDULING_TRACK,
  PROCESS_SUMMARY_TRACK,
  EXPECTED_FRAMES_SLICE_TRACK,
  ACTUAL_FRAMES_SLICE_TRACK,
  PERF_SAMPLES_PROFILE_TRACK,
  HEAP_PROFILE_TRACK,
  MAIN_THREAD,
  RENDER_THREAD,
  GPU_COMPLETION_THREAD,
  CHROME_IO_THREAD,
  CHROME_COMPOSITOR_THREAD,
  ORDINARY_THREAD,
  COUNTER_TRACK,
  ASYNC_SLICE_TRACK,
  ORDINARY_TRACK,
}

export interface SliceTrackColNames {
  ts: string;
  name: string;
  dur: string;
}

export interface DebugSliceTrackArgs {
  // Title of the track. If omitted a placeholder name will be chosen instead.
  trackName?: string;

  // Mapping definitions of the 'ts', 'dur', and 'name' columns.
  // By default, columns called ts, dur and name will be used.
  // If dur is assigned the value '0', all slices shall be instant events.
  columnMapping?: Partial<SliceTrackColNames>;

  // Any extra columns to be used as args.
  args?: string[];

  // Optional renaming of columns.
  columns?: string[];
}

export interface CounterTrackColNames {
  ts: string;
  value: string;
}

export interface DebugCounterTrackArgs {
  // Title of the track. If omitted a placeholder name will be chosen instead.
  trackName?: string;

  // Mapping definitions of the ts and value columns.
  columnMapping?: Partial<CounterTrackColNames>;
}

// Similar to PluginContext but with additional methods to operate on the
// currently loaded trace. Passed to trace-relevant hooks on a plugin instead of
// PluginContext.
export interface PluginContextTrace extends PluginContext {
  readonly engine: EngineProxy;

  // Control over the main timeline.
  timeline: {
    // Add a new track to the scrolling track section, returning the newly
    // created track key.
    addTrack(uri: string, displayName: string, params?: unknown): string;

    // Remove a single track from the timeline.
    removeTrack(key: string): void;

    // Pin a single track.
    pinTrack(key: string): void;

    // Unpin a single track.
    unpinTrack(key: string): void;

    // Pin all tracks that match a predicate.
    pinTracksByPredicate(predicate: TrackPredicate): void;

    // Unpin all tracks that match a predicate.
    unpinTracksByPredicate(predicate: TrackPredicate): void;

    // Remove all tracks that match a predicate.
    removeTracksByPredicate(predicate: TrackPredicate): void;

    // Retrieve a list of tracks on the timeline.
    tracks: TrackRef[];

    // Bring a timestamp into view.
    panToTimestamp(ts: time): void;
  }

  // Control over the bottom details pane.
  tabs: {
    // Creates a new tab running the provided query.
    openQuery(query: string, title: string): void;
  }

  // Register a new track against a unique key known as a URI.
  // Once a track is registered it can be referenced multiple times on the
  // timeline with different params to allow customising each instance.
  registerTrack(trackDesc: TrackDescriptor): void;

  // Add a new entry to the pool of default tracks. Default tracks are a list
  // of track references that describe the list of tracks that should be added
  // to the main timeline on startup.
  // Default tracks are only used when a trace is first loaded, not when
  // loading from a permalink, where the existing list of tracks from the
  // shared state is used instead.
  addDefaultTrack(track: TrackRef): void;

  // Simultaneously register a track and add it as a default track in one go.
  // This is simply a helper which calls registerTrack() and addDefaultTrack()
  // with the same URI.
  registerStaticTrack(track: TrackDescriptor&TrackRef): void;

  // Create a store mounted over the top of this plugin's persistent state.
  mountStore<T>(migrate: Migrate<T>): Store<T>;
}

export interface Plugin {
  // Lifecycle methods.
  onActivate(ctx: PluginContext): void;
  onTraceLoad?(ctx: PluginContextTrace): Promise<void>;
  onTraceUnload?(ctx: PluginContextTrace): Promise<void>;
  onDeactivate?(ctx: PluginContext): void;

  // Extension points.
  metricVisualisations?(ctx: PluginContext): MetricVisualisation[];
}

// This interface defines what a plugin factory should look like.
// This can be defined in the plugin class definition by defining a constructor
// and the relevant static methods:
// E.g.
// class MyPlugin implements TracePlugin<MyState> {
//   migrate(initialState: unknown): MyState {...}
//   constructor(store: Store<MyState>, engine: EngineProxy) {...}
//   ... methods from the TracePlugin interface go here ...
// }
// ... which can then be passed around by class i.e. MyPlugin
export interface PluginClass {
  // Instantiate the plugin.
  new(): Plugin;
}

// Describes a reference to a registered track.
export interface TrackRef {
  // URI of the registered track.
  uri: string;

  // A human readable name for this track - displayed in the track shell.
  displayName: string;

  // Optional: An opaque object used to customize this instance of the track.
  params?: unknown;

  // Optional: Used to define default sort order for new traces.
  // Note: This will be deprecated soon in favour of tags & sort rules.
  sortKey?: PrimaryTrackSortKey;
}

// A predicate for selecting a groups of tracks.
export type TrackPredicate = (info: TrackTags) => boolean;

interface WellKnownTrackTags {
  // A human readable name for this specific track.
  name: string;

  // Controls whether to show the "metric" chip.
  metric: boolean;

  // Controls whether to show the "debuggable" chip.
  debuggable: boolean;
}

// An set of key/value pairs describing a given track. These are used for
// selecting tracks to pin/unpin, diplsaying "chips" in the track shell, and
// (in future) the sorting and grouping of tracks.
// We define a handful of well known fields, and the rest are arbitrary key-
// value pairs.
export type TrackTags = Partial<WellKnownTrackTags>&{
  // There may be arbitrary other key/value pairs.
  [key: string]: string|number|boolean|undefined;
}

// Plugins can be passed as class refs, factory functions, or concrete plugin
// implementations.
export type PluginFactory = PluginClass|Plugin|(() => Plugin);

export interface PluginDescriptor {
  // A unique string for your plugin. To ensure the name is unique you
  // may wish to use a URL with reversed components in the manner of
  // Java package names.
  pluginId: string;

  // The plugin factory used to instantiate the plugin object, or if this is
  // an actual plugin implementation, it's just used as-is.
  plugin: PluginFactory;
}
