// 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 {Disposable, DisposableCallback} from '../base/disposable';
import {PanelSize} from '../frontend/panel';
import {exists} from '../base/utils';
import {Store} from '../frontend/store';
import {
  Migrate,
  Track,
  TrackContext,
  TrackDescriptor,
  TrackRef,
} from '../public';
import {Registry} from './registry';

import {ObjectByKey, State, TrackState} from './state';

export interface TrackCacheEntry {
  track: Track;
  desc: TrackDescriptor;
  update(): void;
  render(ctx: CanvasRenderingContext2D, size: PanelSize): void;
  destroy(): void;
  getError(): Error | undefined;
}

// This class is responsible for managing the lifecycle of tracks over render
// cycles.

// Example usage:
// function render() {
//   const trackCache = new TrackCache();
//   const foo = trackCache.resolveTrack('foo', 'exampleURI', {});
//   const bar = trackCache.resolveTrack('bar', 'exampleURI', {});
//   trackCache.flushOldTracks(); // <-- Destroys any unused cached tracks
// }

// Example of how flushing works:
// First cycle
//   resolveTrack('foo', ...) <-- new track 'foo' created
//   resolveTrack('bar', ...) <-- new track 'bar' created
//   flushTracks()
// Second cycle
//   resolveTrack('foo', ...) <-- returns cached 'foo' track
//   flushTracks() <-- 'bar' is destroyed, as it was not resolved this cycle
// Third cycle
//   flushTracks() <-- 'foo' is destroyed.
export class TrackManager {
  private _trackKeyByTrackId = new Map<number, string>();
  private newTracks = new Map<string, TrackCacheEntry>();
  private currentTracks = new Map<string, TrackCacheEntry>();
  private trackRegistry = new Registry<TrackDescriptor>(({uri}) => uri);
  private defaultTracks = new Set<TrackRef>();

  private store: Store<State>;
  private trackState?: ObjectByKey<TrackState>;

  constructor(store: Store<State>) {
    this.store = store;
  }

  get trackKeyByTrackId() {
    this.updateTrackKeyByTrackIdMap();
    return this._trackKeyByTrackId;
  }

  registerTrack(trackDesc: TrackDescriptor): Disposable {
    return this.trackRegistry.register(trackDesc);
  }

  addPotentialTrack(track: TrackRef): Disposable {
    this.defaultTracks.add(track);
    return new DisposableCallback(() => {
      this.defaultTracks.delete(track);
    });
  }

  findPotentialTracks(): TrackRef[] {
    return Array.from(this.defaultTracks);
  }

  getAllTracks(): TrackDescriptor[] {
    return Array.from(this.trackRegistry.values());
  }

  // Look up track into for a given track's URI.
  // Returns |undefined| if no track can be found.
  resolveTrackInfo(uri: string): TrackDescriptor|undefined {
    return this.trackRegistry.tryGet(uri);
  }

  // Creates a new track using |uri| and |params| or retrieves a cached track if
  // |key| exists in the cache.
  resolveTrack(key: string, trackDesc: TrackDescriptor, params?: unknown):
      TrackCacheEntry {
    // Search for a cached version of this track,
    const cached = this.currentTracks.get(key);

    // Ensure the cached track has the same factory type as the resolved track.
    // If this has changed, the track should be re-created.
    if (cached && trackDesc.trackFactory === cached.desc.trackFactory) {
      // Keep our cached track descriptor up to date, if anything's changed.
      cached.desc = trackDesc;

      // Move this track from the recycle bin to the safe cache, which means
      // it's safe from disposal for this cycle.
      this.newTracks.set(key, cached);

      return cached;
    } else {
      // Cached track doesn't exist or is out of date, create a new one.
      const trackContext: TrackContext = {
        trackKey: key,
        mountStore: <T>(migrate: Migrate<T>) => {
          const path = ['tracks', key, 'state'];
          return this.store.createSubStore(path, migrate);
        },
        params,
      };
      const track = trackDesc.trackFactory(trackContext);
      const entry = new TrackFSM(track, trackDesc, trackContext);

      // Push track into the safe cache.
      this.newTracks.set(key, entry);
      return entry;
    }
  }

  // Destroys all current tracks not present in the new cache.
  flushOldTracks() {
    for (const [key, entry] of this.currentTracks.entries()) {
      if (!this.newTracks.has(key)) {
        entry.destroy();
      }
    }

    this.currentTracks = this.newTracks;
    this.newTracks = new Map<string, TrackCacheEntry>();
  }

  private updateTrackKeyByTrackIdMap() {
    if (this.trackState === this.store.state.tracks) {
      return;
    }

    const trackKeyByTrackId = new Map<number, string>();

    const trackList = Object.entries(this.store.state.tracks);
    trackList.forEach(([key, {uri}]) => {
      const desc = this.trackRegistry.get(uri);
      for (const trackId of desc?.trackIds ?? []) {
        const existingKey = trackKeyByTrackId.get(trackId);
        if (exists(existingKey)) {
          throw new Error(`Trying to map track id ${trackId} to UI track ${key}, already mapped to ${existingKey}`);
        }
        trackKeyByTrackId.set(trackId, key);
      }
    });

    this._trackKeyByTrackId = trackKeyByTrackId;
    this.trackState = this.store.state.tracks;
  }
}

enum TrackFSMState {
  Creating = 'creating',
  Ready = 'ready',
  UpdatePending = 'update_pending',
  Updating = 'updating',
  DestroyPending = 'destroy_pending',
  Destroyed = 'destroyed',  // <- Final state, cannot escape.
  Error = 'error',
}

/**
 * Wrapper that manages lifecycle hooks on behalf of a track, ensuring lifecycle
 * hooks are called synchronously and in the correct order.
 */
class TrackFSM implements TrackCacheEntry {
  private state: TrackFSMState;
  private error?: Error;

  constructor(
      public track: Track, public desc: TrackDescriptor, ctx: TrackContext) {
    this.state = TrackFSMState.Creating;
    const result = this.track.onCreate?.(ctx);
    Promise.resolve(result)
      .then(() => this.onTrackCreated())
      .catch((e) => {
        this.error = e;
        this.state = TrackFSMState.Error;
      });
  }

  update(): void {
    switch (this.state) {
    case TrackFSMState.Creating:
    case TrackFSMState.Updating:
      this.state = TrackFSMState.UpdatePending;
      break;
    case TrackFSMState.Ready:
      const result = this.track.onUpdate?.();
      Promise.resolve(result)
        .then(() => this.onTrackUpdated())
        .catch((e) => {
          this.error = e;
          this.state = TrackFSMState.Error;
        });
      this.state = TrackFSMState.Updating;
      break;
    case TrackFSMState.UpdatePending:
      // Update already pending... do nothing!
      break;
    case TrackFSMState.Error:
      break;
    default:
      throw new Error('Invalid state transition');
    }
  }

  destroy(): void {
    switch (this.state) {
    case TrackFSMState.Ready:
      // Don't bother awaiting this as the track can no longer be used.
      Promise.resolve(this.track.onDestroy?.())
        .catch(() => {
          // Track crashed while being destroyed
          // There's not a lot we can do here - just swallow the error
        });
      this.state = TrackFSMState.Destroyed;
      break;
    case TrackFSMState.Creating:
    case TrackFSMState.Updating:
    case TrackFSMState.UpdatePending:
      this.state = TrackFSMState.DestroyPending;
      break;
    case TrackFSMState.Error:
      break;
    default:
      throw new Error('Invalid state transition');
    }
  }

  private onTrackCreated() {
    switch (this.state) {
    case TrackFSMState.DestroyPending:
      // Don't bother awaiting this as the track can no longer be used.
      this.track.onDestroy?.();
      this.state = TrackFSMState.Destroyed;
      break;
    case TrackFSMState.UpdatePending:
      const result = this.track.onUpdate?.();
      Promise.resolve(result)
        .then(() => this.onTrackUpdated())
        .catch((e) => {
          this.error = e;
          this.state = TrackFSMState.Error;
        });
      this.state = TrackFSMState.Updating;
      break;
    case TrackFSMState.Creating:
      this.state = TrackFSMState.Ready;
      break;
    case TrackFSMState.Error:
      break;
    default:
      throw new Error('Invalid state transition');
    }
  }

  private onTrackUpdated() {
    switch (this.state) {
    case TrackFSMState.DestroyPending:
      // Don't bother awaiting this as the track can no longer be used.
      this.track.onDestroy?.();
      this.state = TrackFSMState.Destroyed;
      break;
    case TrackFSMState.UpdatePending:
      const result = this.track.onUpdate?.();
      Promise.resolve(result)
        .then(() => this.onTrackUpdated())
        .catch((e) => {
          this.error = e;
          this.state = TrackFSMState.Error;
        });
      this.state = TrackFSMState.Updating;
      break;
    case TrackFSMState.Updating:
      this.state = TrackFSMState.Ready;
      break;
    case TrackFSMState.Error:
      break;
    default:
      throw new Error('Invalid state transition');
    }
  }

  render(ctx: CanvasRenderingContext2D, size: PanelSize): void {
    try {
      this.track.render(ctx, size);
    } catch {
      this.state = TrackFSMState.Error;
    }
  }

  getError(): Error | undefined {
    if (this.state === TrackFSMState.Error) {
      return this.error;
    } else {
      return undefined;
    }
  }
}
