// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use size 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 {Engine} from '../common/engine';
import {featureFlags} from '../common/feature_flags';
import {NUM, STR_NULL} from '../common/query_result';
import {Area} from '../common/state';
import {fromNs, toNs} from '../common/time';
import {Flow} from '../frontend/globals';
import {publishConnectedFlows, publishSelectedFlows} from '../frontend/publish';
import {
  ACTUAL_FRAMES_SLICE_TRACK_KIND,
  Config as ActualConfig
} from '../tracks/actual_frames/common';
import {
  Config as SliceConfig,
  SLICE_TRACK_KIND
} from '../tracks/chrome_slices/common';

import {Controller} from './controller';
import {globals} from './globals';

export interface FlowEventsControllerArgs {
  engine: Engine;
}

const SHOW_INDIRECT_PRECEDING_FLOWS_FLAG = featureFlags.register({
  id: 'showIndirectPrecedingFlows',
  name: 'Show indirect preceding flows',
  description: 'Show indirect preceding flows (connected through ancestor ' +
      'slices) when a slice is selected.',
  defaultValue: false,
});


export class FlowEventsController extends Controller<'main'> {
  private lastSelectedSliceId?: number;
  private lastSelectedArea?: Area;
  private lastSelectedKind: 'CHROME_SLICE'|'AREA'|'NONE' = 'NONE';

  constructor(private args: FlowEventsControllerArgs) {
    super('main');
  }

  queryFlowEvents(query: string, callback: (flows: Flow[]) => void) {
    this.args.engine.query(query).then(result => {
      const flows: Flow[] = [];
      const it = result.iter({
        beginSliceId: NUM,
        beginTrackId: NUM,
        beginSliceName: STR_NULL,
        beginSliceCategory: STR_NULL,
        beginSliceStartTs: NUM,
        beginSliceEndTs: NUM,
        beginDepth: NUM,
        beginThreadName: STR_NULL,
        beginProcessName: STR_NULL,
        endSliceId: NUM,
        endTrackId: NUM,
        endSliceName: STR_NULL,
        endSliceCategory: STR_NULL,
        endSliceStartTs: NUM,
        endSliceEndTs: NUM,
        endDepth: NUM,
        endThreadName: STR_NULL,
        endProcessName: STR_NULL,
        name: STR_NULL,
        category: STR_NULL,
        id: NUM,
      });
      for (; it.valid(); it.next()) {
        const beginSliceId = it.beginSliceId;
        const beginTrackId = it.beginTrackId;
        const beginSliceName =
            it.beginSliceName === null ? 'NULL' : it.beginSliceName;
        const beginSliceCategory =
            it.beginSliceCategory === null ? 'NULL' : it.beginSliceCategory;
        const beginSliceStartTs = fromNs(it.beginSliceStartTs);
        const beginSliceEndTs = fromNs(it.beginSliceEndTs);
        const beginDepth = it.beginDepth;
        const beginThreadName =
            it.beginThreadName === null ? 'NULL' : it.beginThreadName;
        const beginProcessName =
            it.beginProcessName === null ? 'NULL' : it.beginProcessName;

        const endSliceId = it.endSliceId;
        const endTrackId = it.endTrackId;
        const endSliceName =
            it.endSliceName === null ? 'NULL' : it.endSliceName;
        const endSliceCategory =
            it.endSliceCategory === null ? 'NULL' : it.endSliceCategory;
        const endSliceStartTs = fromNs(it.endSliceStartTs);
        const endSliceEndTs = fromNs(it.endSliceEndTs);
        const endDepth = it.endDepth;
        const endThreadName =
            it.endThreadName === null ? 'NULL' : it.endThreadName;
        const endProcessName =
            it.endProcessName === null ? 'NULL' : it.endProcessName;

        // Category and name present only in version 1 flow events
        // It is most likelly NULL for all other versions
        const category = it.category === null ? undefined : it.category;
        const name = it.name === null ? undefined : it.name;
        const id = it.id;

        flows.push({
          id,
          begin: {
            trackId: beginTrackId,
            sliceId: beginSliceId,
            sliceName: beginSliceName,
            sliceCategory: beginSliceCategory,
            sliceStartTs: beginSliceStartTs,
            sliceEndTs: beginSliceEndTs,
            depth: beginDepth,
            threadName: beginThreadName,
            processName: beginProcessName
          },
          end: {
            trackId: endTrackId,
            sliceId: endSliceId,
            sliceName: endSliceName,
            sliceCategory: endSliceCategory,
            sliceStartTs: endSliceStartTs,
            sliceEndTs: endSliceEndTs,
            depth: endDepth,
            threadName: endThreadName,
            processName: endProcessName
          },
          dur: endSliceStartTs - beginSliceEndTs,
          category,
          name
        });
      }
      callback(flows);
    });
  }

  sliceSelected(sliceId: number) {
    if (this.lastSelectedKind === 'CHROME_SLICE' &&
        this.lastSelectedSliceId === sliceId) {
      return;
    }
    this.lastSelectedSliceId = sliceId;
    this.lastSelectedKind = 'CHROME_SLICE';

    const connectedFlows = SHOW_INDIRECT_PRECEDING_FLOWS_FLAG.get() ?
        `(
           select * from directly_connected_flow(${sliceId})
           union
           select * from preceding_flow(${sliceId})
         )` :
        `directly_connected_flow(${sliceId})`;

    const query = `
    select
      f.slice_out as beginSliceId,
      t1.track_id as beginTrackId,
      t1.name as beginSliceName,
      t1.category as beginSliceCategory,
      t1.ts as beginSliceStartTs,
      (t1.ts+t1.dur) as beginSliceEndTs,
      t1.depth as beginDepth,
      (thread_out.name || ' ' || thread_out.tid) as beginThreadName,
      (process_out.name || ' ' || process_out.pid) as beginProcessName,
      f.slice_in as endSliceId,
      t2.track_id as endTrackId,
      t2.name as endSliceName,
      t2.category as endSliceCategory,
      t2.ts as endSliceStartTs,
      (t2.ts+t2.dur) as endSliceEndTs,
      t2.depth as endDepth,
      (thread_in.name || ' ' || thread_in.tid) as endThreadName,
      (process_in.name || ' ' || process_in.pid) as endProcessName,
      extract_arg(f.arg_set_id, 'cat') as category,
      extract_arg(f.arg_set_id, 'name') as name,
      f.id as id
    from ${connectedFlows} f
    join slice t1 on f.slice_out = t1.slice_id
    join slice t2 on f.slice_in = t2.slice_id
    left join thread_track track_out on track_out.id = t1.track_id
    left join thread thread_out on thread_out.utid = track_out.utid
    left join thread_track track_in on track_in.id = t2.track_id
    left join thread thread_in on thread_in.utid = track_in.utid
    left join process process_out on process_out.upid = thread_out.upid
    left join process process_in on process_in.upid = thread_in.upid
    `;
    this.queryFlowEvents(
        query, (flows: Flow[]) => publishConnectedFlows(flows));
  }

  areaSelected(areaId: string) {
    const area = globals.state.areas[areaId];
    if (this.lastSelectedKind === 'AREA' && this.lastSelectedArea &&
        this.lastSelectedArea.tracks.join(',') === area.tracks.join(',') &&
        this.lastSelectedArea.endSec === area.endSec &&
        this.lastSelectedArea.startSec === area.startSec) {
      return;
    }

    this.lastSelectedArea = area;
    this.lastSelectedKind = 'AREA';

    const trackIds: number[] = [];

    for (const uiTrackId of area.tracks) {
      const track = globals.state.tracks[uiTrackId];
      if (track === undefined) {
        continue;
      }
      if (track.kind === SLICE_TRACK_KIND) {
        trackIds.push((track.config as SliceConfig).trackId);
      } else if (track.kind === ACTUAL_FRAMES_SLICE_TRACK_KIND) {
        const actualConfig = track.config as ActualConfig;
        for (const trackId of actualConfig.trackIds) {
          trackIds.push(trackId);
        }
      }
    }

    const tracks = `(${trackIds.join(',')})`;

    const startNs = toNs(area.startSec);
    const endNs = toNs(area.endSec);

    const query = `
    select
      f.slice_out as beginSliceId,
      t1.track_id as beginTrackId,
      t1.name as beginSliceName,
      t1.category as beginSliceCategory,
      t1.ts as beginSliceStartTs,
      (t1.ts+t1.dur) as beginSliceEndTs,
      t1.depth as beginDepth,
      NULL as beginThreadName,
      NULL as beginProcessName,
      f.slice_in as endSliceId,
      t2.track_id as endTrackId,
      t2.name as endSliceName,
      t2.category as endSliceCategory,
      t2.ts as endSliceStartTs,
      (t2.ts+t2.dur) as endSliceEndTs,
      t2.depth as endDepth,
      NULL as endThreadName,
      NULL as endProcessName,
      extract_arg(f.arg_set_id, 'cat') as category,
      extract_arg(f.arg_set_id, 'name') as name,
      f.id as id
    from flow f
    join slice t1 on f.slice_out = t1.slice_id
    join slice t2 on f.slice_in = t2.slice_id
    where
      (t1.track_id in ${tracks}
        and (t1.ts+t1.dur <= ${endNs} and t1.ts+t1.dur >= ${startNs}))
      or
      (t2.track_id in ${tracks}
        and (t2.ts <= ${endNs} and t2.ts >= ${startNs}))
    `;
    this.queryFlowEvents(query, (flows: Flow[]) => publishSelectedFlows(flows));
  }

  refreshVisibleFlows() {
    const selection = globals.state.currentSelection;
    if (!selection) {
      this.lastSelectedKind = 'NONE';
      publishConnectedFlows([]);
      publishSelectedFlows([]);
      return;
    }

    // TODO(b/155483804): This is a hack as annotation slices don't contain
    // flows. We should tidy this up when fixing this bug.
    if (selection && selection.kind === 'CHROME_SLICE' &&
        selection.table !== 'annotation') {
      this.sliceSelected(selection.id);
    } else {
      publishConnectedFlows([]);
    }

    if (selection && selection.kind === 'AREA') {
      this.areaSelected(selection.areaId);
    } else {
      publishSelectedFlows([]);
    }
  }

  run() {
    this.refreshVisibleFlows();
  }
}
