// 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 {v4 as uuidv4} from 'uuid';

import {Actions, AddTrackArgs} from '../common/actions';
import {Engine} from '../common/engine';
import {NUM} from '../common/query_result';
import {InThreadTrackSortKey} from '../common/state';
import {globals} from '../frontend/globals';
import {
  VISUALISED_ARGS_SLICE_TRACK_KIND,
} from '../tracks/visualised_args/index';

import {Controller} from './controller';

export interface VisualisedArgControllerArgs {
  argName: string;
  engine: Engine;
}

export class VisualisedArgController extends Controller<'init'|'running'> {
  private engine: Engine;
  private argName: string;
  private escapedArgName: string;
  private tableName: string;
  private addedTrackIds: string[];

  constructor(args: VisualisedArgControllerArgs) {
    super('init');
    this.argName = args.argName;
    this.engine = args.engine;
    this.escapedArgName = this.argName.replace(/[^a-zA-Z]/g, '_');
    this.tableName = `__arg_visualisation_helper_${this.escapedArgName}_slice`;
    this.addedTrackIds = [];
  }

  onDestroy() {
    this.engine.query(`drop table if exists ${this.tableName}`);
    globals.dispatch(
        Actions.removeVisualisedArgTracks({trackIds: this.addedTrackIds}));
  }

  async createTracks() {
    const result = await this.engine.query(`
        drop table if exists ${this.tableName};

        create table ${this.tableName} as
        with slice_with_arg as (
          select
            slice.id,
            slice.track_id,
            slice.ts,
            slice.dur,
            slice.thread_dur,
            NULL as cat,
            args.display_value as name
          from slice
          join args using (arg_set_id)
          where args.key='${this.argName}'
        )
        select
          *,
          (select count()
           from ancestor_slice(s1.id) s2
           join slice_with_arg s3 on s2.id=s3.id
          ) as depth
        from slice_with_arg s1
        order by id;

        select
          track_id as trackId,
          max(depth) as maxDepth
        from ${this.tableName}
        group by track_id;
    `);

    const tracksToAdd: AddTrackArgs[] = [];
    const it = result.iter({'trackId': NUM, 'maxDepth': NUM});
    for (; it.valid(); it.next()) {
      const track =
          globals.state
              .tracks[globals.state.uiTrackIdByTraceTrackId[it.trackId]];
      const utid = (track.trackSortKey as {utid?: number}).utid;
      const id = uuidv4();
      this.addedTrackIds.push(id);
      tracksToAdd.push({
        id,
        trackGroup: track.trackGroup,
        engineId: this.engine.id,
        kind: VISUALISED_ARGS_SLICE_TRACK_KIND,
        name: this.argName,
        trackSortKey: utid === undefined ?
            track.trackSortKey :
            {utid, priority: InThreadTrackSortKey.VISUALISED_ARGS_TRACK},
        config: {
          maxDepth: it.maxDepth,
          namespace: `__arg_visualisation_helper_${this.escapedArgName}`,
          trackId: it.trackId,
          argName: this.argName,
          tid: (track.config as {tid?: number}).tid,
        },
      });
    }
    globals.dispatch(Actions.addTracks({tracks: tracksToAdd}));
    globals.dispatch(Actions.sortThreadTracks({}));
  }

  run() {
    switch (this.state) {
      case 'init':
        this.createTracks();
        this.setState('running');
        break;
      case 'running':
        // Nothing to do here.
        break;
      default:
        throw new Error(`Unexpected state ${this.state}`);
    }
  }
}
