// 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 {TrackNode} from '../../public/workspace';
import {Trace} from '../../public/trace';
import {PerfettoPlugin} from '../../public/plugin';
import {TrackDescriptor} from '../../public/track';
import {z} from 'zod';
import {
  base64Decode,
  base64Encode,
  utf8Decode,
  utf8Encode,
} from '../../base/string_utils';
import {assertExists} from '../../base/logging';

const PLUGIN_ID = 'dev.perfetto.RestorePinnedTrack';
const SAVED_TRACKS_KEY = `${PLUGIN_ID}#savedPerfettoTracks`;

const RESTORE_COMMAND_ID = `${PLUGIN_ID}#restore`;

/**
 * Fuzzy save and restore of pinned tracks.
 *
 * Tries to persist pinned tracks. Uses full string matching between track name
 * and group name. When no match is found for a saved track, it tries again
 * without numbers.
 */
export default class implements PerfettoPlugin {
  static readonly id = PLUGIN_ID;
  private ctx!: Trace;

  async onTraceLoad(ctx: Trace): Promise<void> {
    this.ctx = ctx;

    ctx.commands.registerCommand({
      id: `${PLUGIN_ID}#save`,
      name: 'Save: Pinned tracks',
      callback: () => {
        this.savedState = {
          ...this.savedState,
          tracks: this.getCurrentPinnedTracks(),
        };
      },
    });
    ctx.commands.registerCommand({
      id: RESTORE_COMMAND_ID,
      name: 'Restore: Pinned tracks',
      callback: () => {
        const tracks = this.savedState?.tracks;
        if (!tracks) {
          alert('No saved tracks. Use the Save command first');
          return;
        }
        this.restoreTracks(tracks);
      },
    });

    ctx.commands.registerCommand({
      id: `${PLUGIN_ID}#saveByName`,
      name: 'Save by name: Pinned tracks',
      callback: async () => {
        const res = await this.ctx.omnibox.prompt(
          'Give a name to the pinned set of tracks',
        );
        if (res) {
          const rawTracksByName = this.savedState?.tracksByName ?? [];
          const tracksByNameMap = new Map(
            rawTracksByName.map((x) => [x.name, x.tracks]),
          );
          tracksByNameMap.set(
            base64Encode(utf8Encode(res)),
            this.getCurrentPinnedTracks(),
          );
          this.savedState = {
            ...this.savedState,
            tracksByName: Array.from(tracksByNameMap.entries()).map(
              ([k, v]) => ({
                name: k,
                tracks: v,
              }),
            ),
          };
        }
      },
    });
    ctx.commands.registerCommand({
      id: `${PLUGIN_ID}#restoreByName`,
      name: 'Restore by name: Pinned tracks',
      callback: async () => {
        const tracksByName = this.savedState?.tracksByName ?? [];
        if (tracksByName.length === 0) {
          alert('No saved tracks. Use the Save by name command first');
          return;
        }
        const res = await this.ctx.omnibox.prompt(
          'Select name of set of pinned tracks to restore',
          tracksByName.map((x) => ({
            key: x.name,
            displayName: utf8Decode(base64Decode(x.name)),
          })),
        );
        if (res) {
          const tracks = assertExists(
            tracksByName.find((x) => x.name === res)?.tracks,
          );
          this.restoreTracks(tracks);
        }
      },
    });
  }

  private restoreTracks(tracks: ReadonlyArray<SavedPinnedTrack>) {
    const localTracks = this.ctx.workspace.flatTracks.map((track) => ({
      savedTrack: this.toSavedTrack(track),
      track: track,
    }));
    tracks.forEach((trackToRestore) => {
      const foundTrack = this.findMatchingTrack(localTracks, trackToRestore);
      if (foundTrack) {
        foundTrack.pin();
      } else {
        console.warn(
          '[RestorePinnedTracks] No track found that matches',
          trackToRestore,
        );
      }
    });
  }

  private getCurrentPinnedTracks() {
    return this.ctx.workspace.pinnedTracks.map((track) =>
      this.toSavedTrack(track),
    );
  }

  private findMatchingTrack(
    localTracks: Array<LocalTrack>,
    savedTrack: SavedPinnedTrack,
  ): TrackNode | undefined {
    let mostSimilarTrack: LocalTrack | undefined = undefined;
    let mostSimilarTrackDifferenceScore: number = 0;

    for (let i = 0; i < localTracks.length; i++) {
      const localTrack = localTracks[i];
      const differenceScore = this.calculateSimilarityScore(
        localTrack.savedTrack,
        savedTrack,
      );

      // Return immediately if we found the exact match
      if (differenceScore === Number.MAX_SAFE_INTEGER) {
        return localTrack.track;
      }

      // Ignore too different objects
      if (differenceScore === 0) {
        continue;
      }

      if (differenceScore > mostSimilarTrackDifferenceScore) {
        mostSimilarTrackDifferenceScore = differenceScore;
        mostSimilarTrack = localTrack;
      }
    }

    return mostSimilarTrack?.track || undefined;
  }

  /**
   * Returns the similarity score where 0 means the objects are completely
   * different, and the higher the number, the smaller the difference is.
   * Returns Number.MAX_SAFE_INTEGER if the objects are completely equal.
   * We attempt a fuzzy match based on the similarity score.
   * For example, one of the ways we do this is we remove the numbers
   * from the title to potentially pin a "similar" track from a different trace.
   * Removing numbers allows flexibility; for instance, with multiple 'sysui'
   * processes (e.g. track group name: "com.android.systemui 123") without
   * this approach, any could be mistakenly pinned. The goal is to restore
   * specific tracks within the same trace, ensuring that a previously pinned
   * track is pinned again.
   * If the specific process with that PID is unavailable, pinning any
   * other process matching the package name is attempted.
   * @param track1 first saved track to compare
   * @param track2 second saved track to compare
   * @private
   */
  private calculateSimilarityScore(
    track1: SavedPinnedTrack,
    track2: SavedPinnedTrack,
  ): number {
    // Return immediately when objects are equal
    if (
      track1.trackName === track2.trackName &&
      track1.groupName === track2.groupName &&
      track1.pluginId === track2.pluginId &&
      track1.kind === track2.kind &&
      track1.isMainThread === track2.isMainThread
    ) {
      return Number.MAX_SAFE_INTEGER;
    }

    let similarityScore = 0;
    if (track1.trackName === track2.trackName) {
      similarityScore += 100;
    } else if (
      this.removeNumbers(track1.trackName) ===
      this.removeNumbers(track2.trackName)
    ) {
      similarityScore += 50;
    }

    if (track1.groupName === track2.groupName) {
      similarityScore += 90;
    } else if (
      this.removeNumbers(track1.groupName) ===
      this.removeNumbers(track2.groupName)
    ) {
      similarityScore += 45;
    }

    // Do not consider other parameters if there is no match in name/group
    if (similarityScore === 0) return similarityScore;

    if (track1.pluginId === track2.pluginId) {
      similarityScore += 30;
    }

    if (track1.kind === track2.kind) {
      similarityScore += 20;
    }

    if (track1.isMainThread === track2.isMainThread) {
      similarityScore += 10;
    }

    return similarityScore;
  }

  private removeNumbers(inputString?: string): string | undefined {
    return inputString?.replace(/\d+/g, '');
  }

  private toSavedTrack(track: TrackNode): SavedPinnedTrack {
    let trackDescriptor: TrackDescriptor | undefined = undefined;
    if (track.uri != undefined) {
      trackDescriptor = this.ctx.tracks.getTrack(track.uri);
    }

    return {
      groupName: groupName(track),
      trackName: track.title,
      pluginId: trackDescriptor?.pluginId,
      kind: trackDescriptor?.tags?.kind,
      isMainThread: trackDescriptor?.chips?.includes('main thread') || false,
    };
  }

  private get savedState(): SavedState | undefined {
    const savedStateString = window.localStorage.getItem(SAVED_TRACKS_KEY);
    if (!savedStateString) {
      return undefined;
    }
    const savedState = SAVED_STATE_SCHEMA.safeParse(
      JSON.parse(savedStateString),
    );
    if (!savedState.success) {
      return undefined;
    }
    return savedState.data;
  }

  private set savedState(state: SavedState) {
    window.localStorage.setItem(SAVED_TRACKS_KEY, JSON.stringify(state));
  }
}

// Return the displayname of the containing group
// If the track is a child of a workspace, return undefined...
function groupName(track: TrackNode): string | undefined {
  const parent = track.parent;
  if (parent instanceof TrackNode) {
    return parent.title;
  }
  return undefined;
}

const SAVED_PINNED_TRACK_SCHEMA = z
  .object({
    // Optional: group name for the track. Usually matches with process name.
    groupName: z.string().optional(),
    // Track name to restore.
    trackName: z.string(),
    // Plugin used to create this track
    pluginId: z.string().optional(),
    // Kind of the track
    kind: z.string().optional(),
    // If it's a thread track, it should be true in case it's a main thread track
    isMainThread: z.boolean(),
  })
  .readonly();

type SavedPinnedTrack = z.infer<typeof SAVED_PINNED_TRACK_SCHEMA>;

const SAVED_STATE_SCHEMA = z
  .object({
    tracks: z.array(SAVED_PINNED_TRACK_SCHEMA).optional().readonly(),
    tracksByName: z
      .array(
        z
          .object({
            name: z.string(),
            tracks: z.array(SAVED_PINNED_TRACK_SCHEMA).readonly(),
          })
          .readonly(),
      )
      .optional()
      .readonly(),
  })
  .readonly();

type SavedState = z.infer<typeof SAVED_STATE_SCHEMA>;

interface LocalTrack {
  readonly savedTrack: SavedPinnedTrack;
  readonly track: TrackNode;
}
