// 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 {
  createStore,
  MetricVisualisation,
  Plugin,
  PluginContext,
  PluginContextTrace,
  PluginDescriptor,
  Store,
} from '../../public';

interface State {
  foo: string;
}

// SKELETON: Rename this class to match your plugin.
class Skeleton implements Plugin {
  private store: Store<State> = createStore({foo: 'foo'});

  /**
   * This hook is called when the plugin is activated manually, or when the UI
   * starts up with this plugin enabled. This is typically before a trace has
   * been loaded, so there is no trace information in the passed plugin context
   * object.
   *
   * This hook should be used for adding commands that don't depend on the
   * trace.
   */
  onActivate(_: PluginContext): void {
    //
  }

  /**
   * This hook is called as the trace is loading. At this point the trace is
   * loaded into trace processor and it's ready to process queries. This hook
   * should be used for adding tracks and commands that depend on the trace.
   *
   * It should not be used for finding tracks from other plugins as there is no
   * guarantee those tracks will have been added yet.
   */
  async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
    this.store = ctx.mountStore((_: unknown): State => {
      return {foo: 'bar'};
    });

    this.store.edit((state) => {
      state.foo = 'baz';
    });

    // This is an example of how to access the pluginArgs pushed by the
    // postMessage when deep-linking to the UI.
    if (ctx.openerPluginArgs !== undefined) {
      console.log(`Postmessage args for ${ctx.pluginId}`, ctx.openerPluginArgs);
    }
  }

  /**
   * This hook is called when the trace has finished loading, and all plugins
   * have returned from their onTraceLoad calls. The UI can be considered
   * 'ready' at this point. All tracks and commands should now be available, and
   * the timeline is ready to use.
   *
   * This is where any automations should be done - things that you would
   * usually do manually after the trace has loaded but you'd like to automate
   * them.
   *
   * Examples of things that could be done here:
   * - Pinning tracks
   * - Focusing on a slice
   * - Adding debug tracks
   *
   * Postmessage args might be useful here - e.g. if you would like to pin a
   * specific track, pass the track details through the postmessage args
   * interface and react to it here.
   *
   * Note: Any tracks registered in this hook will not be displayed in the
   * timeline, unless they are manually added through the ctx.timeline API.
   * However this part of the code is in flux at the moment and the semantics of
   * how this works might change, though it's still good practice to use the
   * onTraceLoad hook to add tracks as it means that all tracks are available by
   * the time this hook gets called.
   *
   * TODO(stevegolton): Update this comment if the semantics of track adding
   * changes.
   */
  async onTraceReady(_ctx: PluginContextTrace): Promise<void> {}

  /**
   * This hook is called as the trace is being unloaded, such as when switching
   * traces. It should be used to clean up any trace related resources.
   */
  async onTraceUnload(_: PluginContextTrace): Promise<void> {
    this.store[Symbol.dispose]();
  }

  /**
   * This hook is called when this plugin is manually deactivated by the user.
   */
  onDeactivate(_: PluginContext): void {}

  metricVisualisations(_: PluginContextTrace): MetricVisualisation[] {
    return [];
  }
}

export const plugin: PluginDescriptor = {
  // SKELETON: Update pluginId to match the directory of the plugin.
  pluginId: 'com.example.Skeleton',
  plugin: Skeleton,
};
