// Copyright (C) 2018 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 '../tracks/all_controller';

import * as uuidv4 from 'uuid/v4';

import {COUNTER_TRACK_KIND} from '..//tracks/counter/common';
import {assertExists, assertTrue} from '../base/logging';
import {
  Actions,
  AddTrackArgs,
  DeferredAction,
} from '../common/actions';
import {Engine} from '../common/engine';
import {HttpRpcEngine} from '../common/http_rpc_engine';
import {NUM, NUM_NULL, rawQueryToRows, STR_NULL} from '../common/protos';
import {
  EngineMode,
  SCROLLING_TRACK_GROUP,
} from '../common/state';
import {toNs, toNsCeil, toNsFloor} from '../common/time';
import {TimeSpan} from '../common/time';
import {
  createWasmEngine,
  destroyWasmEngine,
  WasmEngineProxy
} from '../common/wasm_engine_proxy';
import {QuantizedLoad, ThreadDesc} from '../frontend/globals';
import {ANDROID_LOGS_TRACK_KIND} from '../tracks/android_log/common';
import {ASYNC_SLICE_TRACK_KIND} from '../tracks/async_slices/common';
import {SLICE_TRACK_KIND} from '../tracks/chrome_slices/common';
import {CPU_FREQ_TRACK_KIND} from '../tracks/cpu_freq/common';
import {CPU_PROFILE_TRACK_KIND} from '../tracks/cpu_profile/common';
import {CPU_SLICE_TRACK_KIND} from '../tracks/cpu_slices/common';
import {HEAP_PROFILE_TRACK_KIND} from '../tracks/heap_profile/common';
import {
  PROCESS_SCHEDULING_TRACK_KIND
} from '../tracks/process_scheduling/common';
import {PROCESS_SUMMARY_TRACK} from '../tracks/process_summary/common';
import {THREAD_STATE_TRACK_KIND} from '../tracks/thread_state/common';

import {
  CounterAggregationController
} from './aggregation/counter_aggregation_controller';
import {
  CpuAggregationController
} from './aggregation/cpu_aggregation_controller';
import {
  SliceAggregationController
} from './aggregation/slice_aggregation_controller';
import {
  ThreadAggregationController
} from './aggregation/thread_aggregation_controller';
import {Child, Children, Controller} from './controller';
import {
  CpuProfileController,
  CpuProfileControllerArgs
} from './cpu_profile_controller';
import {globals} from './globals';
import {
  HeapProfileController,
  HeapProfileControllerArgs
} from './heap_profile_controller';
import {LoadingManager} from './loading_manager';
import {LogsController} from './logs_controller';
import {QueryController, QueryControllerArgs} from './query_controller';
import {SearchController} from './search_controller';
import {
  SelectionController,
  SelectionControllerArgs
} from './selection_controller';
import {
  TraceErrorController,
} from './trace_error_controller';
import {
  TraceBufferStream,
  TraceFileStream,
  TraceHttpStream,
  TraceStream
} from './trace_stream';
import {TrackControllerArgs, trackControllerRegistry} from './track_controller';

type States = 'init'|'loading_trace'|'ready';

interface ThreadSliceTrack {
  maxDepth: number;
  trackId: number;
}

// TraceController handles handshakes with the frontend for everything that
// concerns a single trace. It owns the WASM trace processor engine, handles
// tracks data and SQL queries. There is one TraceController instance for each
// trace opened in the UI (for now only one trace is supported).
export class TraceController extends Controller<States> {
  private readonly engineId: string;
  private engine?: Engine;

  constructor(engineId: string) {
    super('init');
    this.engineId = engineId;
  }

  onDestroy() {
    if (this.engine instanceof WasmEngineProxy) {
      destroyWasmEngine(this.engine.id);
    }
  }

  run() {
    const engineCfg = assertExists(globals.state.engines[this.engineId]);
    switch (this.state) {
      case 'init':
        this.loadTrace()
            .then(mode => {
              globals.dispatch(Actions.setEngineReady({
                engineId: this.engineId,
                ready: true,
                mode,
              }));
            })
            .catch(err => {
              this.updateStatus(`${err}`);
              throw err;
            });
        this.updateStatus('Opening trace');
        this.setState('loading_trace');
        break;

      case 'loading_trace':
        // Stay in this state until loadTrace() returns and marks the engine as
        // ready.
        if (this.engine === undefined || !engineCfg.ready) return;
        this.setState('ready');
        break;

      case 'ready':
        // At this point we are ready to serve queries and handle tracks.
        const engine = assertExists(this.engine);
        assertTrue(engineCfg.ready);
        const childControllers: Children = [];

        // Create a TrackController for each track.
        for (const trackId of Object.keys(globals.state.tracks)) {
          const trackCfg = globals.state.tracks[trackId];
          if (trackCfg.engineId !== this.engineId) continue;
          if (!trackControllerRegistry.has(trackCfg.kind)) continue;
          const trackCtlFactory = trackControllerRegistry.get(trackCfg.kind);
          const trackArgs: TrackControllerArgs = {trackId, engine};
          childControllers.push(Child(trackId, trackCtlFactory, trackArgs));
        }

        // Create a QueryController for each query.
        for (const queryId of Object.keys(globals.state.queries)) {
          const queryArgs: QueryControllerArgs = {queryId, engine};
          childControllers.push(Child(queryId, QueryController, queryArgs));
        }

        const selectionArgs: SelectionControllerArgs = {engine};
        childControllers.push(
            Child('selection', SelectionController, selectionArgs));

        const cpuProfileArgs: CpuProfileControllerArgs = {engine};
        childControllers.push(
            Child('cpuProfile', CpuProfileController, cpuProfileArgs));

        const heapProfileArgs: HeapProfileControllerArgs = {engine};
        childControllers.push(
            Child('heapProfile', HeapProfileController, heapProfileArgs));
        childControllers.push(Child(
            'cpu_aggregation',
            CpuAggregationController,
            {engine, kind: 'cpu_aggregation'}));
        childControllers.push(Child(
            'thread_aggregation',
            ThreadAggregationController,
            {engine, kind: 'thread_state_aggregation'}));
        childControllers.push(Child(
            'slice_aggregation',
            SliceAggregationController,
            {engine, kind: 'slice_aggregation'}));
        childControllers.push(Child(
            'counter_aggregation',
            CounterAggregationController,
            {engine, kind: 'counter_aggregation'}));
        childControllers.push(Child('search', SearchController, {
          engine,
          app: globals,
        }));

        childControllers.push(Child('logs', LogsController, {
          engine,
          app: globals,
        }));
        childControllers.push(
            Child('traceError', TraceErrorController, {engine}));
        return childControllers;

      default:
        throw new Error(`unknown state ${this.state}`);
    }
    return;
  }

  private async loadTrace(): Promise<EngineMode> {
    this.updateStatus('Creating trace processor');
    // Check if there is any instance of the trace_processor_shell running in
    // HTTP RPC mode (i.e. trace_processor_shell -D).
    let engineMode: EngineMode;
    let useRpc = false;
    if (globals.state.newEngineMode === 'USE_HTTP_RPC_IF_AVAILABLE') {
      useRpc = (await HttpRpcEngine.checkConnection()).connected;
    }
    if (useRpc) {
      console.log('Opening trace using native accelerator over HTTP+RPC');
      engineMode = 'HTTP_RPC';
      const engine =
          new HttpRpcEngine(this.engineId, LoadingManager.getInstance);
      engine.errorHandler = (err) => {
        globals.dispatch(
            Actions.setEngineFailed({mode: 'HTTP_RPC', failure: `${err}`}));
        throw err;
      };
      this.engine = engine;
    } else {
      console.log('Opening trace using built-in WASM engine');
      engineMode = 'WASM';
      this.engine = new WasmEngineProxy(
          this.engineId,
          createWasmEngine(this.engineId),
          LoadingManager.getInstance);
    }

    globals.dispatch(Actions.setEngineReady({
      engineId: this.engineId,
      ready: false,
      mode: engineMode,
    }));
    const engineCfg = assertExists(globals.state.engines[this.engineId]);
    let traceStream: TraceStream|undefined;
    if (engineCfg.source.type === 'FILE') {
      traceStream = new TraceFileStream(engineCfg.source.file);
    } else if (engineCfg.source.type === 'ARRAY_BUFFER') {
      traceStream = new TraceBufferStream(engineCfg.source.buffer);
    } else if (engineCfg.source.type === 'URL') {
      traceStream = new TraceHttpStream(engineCfg.source.url);
    } else if (engineCfg.source.type === 'HTTP_RPC') {
      traceStream = undefined;
    } else {
      throw new Error(`Unknown source: ${JSON.stringify(engineCfg.source)}`);
    }

    // |traceStream| can be undefined in the case when we are using the external
    // HTTP+RPC endpoint and the trace processor instance has already loaded
    // a trace (because it was passed as a cmdline argument to
    // trace_processor_shell). In this case we don't want the UI to load any
    // file/stream and we just want to jump to the loading phase.
    if (traceStream !== undefined) {
      const tStart = performance.now();
      for (;;) {
        const res = await traceStream.readChunk();
        await this.engine.parse(res.data);
        const elapsed = (performance.now() - tStart) / 1000;
        let status = 'Loading trace ';
        if (res.bytesTotal > 0) {
          const progress = Math.round(res.bytesRead / res.bytesTotal * 100);
          status += `${progress}%`;
        } else {
          status += `${Math.round(res.bytesRead / 1e6)} MB`;
        }
        status += ` - ${Math.ceil(res.bytesRead / elapsed / 1e6)} MB/s`;
        this.updateStatus(status);
        if (res.eof) break;
      }
      await this.engine.notifyEof();
    } else {
      assertTrue(this.engine instanceof HttpRpcEngine);
      await this.engine.restoreInitialTables();
    }

    const traceTime = await this.engine.getTraceTimeBounds();
    const traceTimeState = {
      startSec: traceTime.start,
      endSec: traceTime.end,
    };
    const actions: DeferredAction[] = [
      Actions.setTraceTime(traceTimeState),
      Actions.navigate({route: '/viewer'}),
    ];

    // We don't know the resolution at this point. However this will be
    // replaced in 50ms so a guess is fine.
    const resolution = (traceTime.end - traceTime.start) / 1000;
    actions.push(Actions.setVisibleTraceTime(
        {...traceTimeState, lastUpdate: Date.now() / 1000, resolution}));

    globals.dispatchMultiple(actions);

    // Make sure the helper views are available before we start adding tracks.
    await this.initialiseHelperViews();

    {
      // When we reload from a permalink don't create extra tracks:
      const {pinnedTracks, tracks} = globals.state;
      if (!pinnedTracks.length && !Object.keys(tracks).length) {
        await this.listTracks();
      }
    }

    await this.listThreads();
    await this.loadTimelineOverview(traceTime);
    return engineMode;
  }

  private async listTracks() {
    this.updateStatus('Loading tracks');

    const engine = assertExists<Engine>(this.engine);
    const numGpus = await engine.getNumberOfGpus();
    const tracksToAdd: AddTrackArgs[] = [];

    const maxCpuFreq = await engine.query(`
      select max(value)
      from counter c
      inner join cpu_counter_track t on c.track_id = t.id
      where name = 'cpufreq';
    `);

    const cpus = await engine.getCpus();

    for (const cpu of cpus) {
      tracksToAdd.push({
        engineId: this.engineId,
        kind: CPU_SLICE_TRACK_KIND,
        name: `Cpu ${cpu}`,
        trackGroup: SCROLLING_TRACK_GROUP,
        config: {
          cpu,
        }
      });
    }

    for (const cpu of cpus) {
      // Only add a cpu freq track if we have
      // cpu freq data.
      // TODO(taylori): Find a way to display cpu idle
      // events even if there are no cpu freq events.
      const cpuFreqIdle = await engine.query(`
        select
          id as cpu_freq_id,
          (
            select id
            from cpu_counter_track
            where name = 'cpuidle'
            and cpu = ${cpu}
            limit 1
          ) as cpu_idle_id
        from cpu_counter_track
        where name = 'cpufreq' and cpu = ${cpu}
        limit 1;
      `);
      if (cpuFreqIdle.numRecords > 0) {
        const freqTrackId = +cpuFreqIdle.columns[0].longValues![0];

        const idleTrackExists: boolean = !cpuFreqIdle.columns[1].isNulls![0];
        const idleTrackId = idleTrackExists ?
            +cpuFreqIdle.columns[1].longValues![0] :
            undefined;

        tracksToAdd.push({
          engineId: this.engineId,
          kind: CPU_FREQ_TRACK_KIND,
          name: `Cpu ${cpu} Frequency`,
          trackGroup: SCROLLING_TRACK_GROUP,
          config: {
            cpu,
            maximumValue: +maxCpuFreq.columns[0].doubleValues![0],
            freqTrackId,
            idleTrackId,
          }
        });
      }
    }

    const rawGlobalAsyncTracks = await engine.query(`
      SELECT
        t.name,
        t.track_ids,
        MAX(experimental_slice_layout.layout_depth) as max_depth
      FROM (
        SELECT name, GROUP_CONCAT(track.id) AS track_ids
        FROM track
        WHERE track.type = "track"
        GROUP BY name
      ) AS t CROSS JOIN experimental_slice_layout
      WHERE t.track_ids = experimental_slice_layout.filter_track_ids
      GROUP BY t.track_ids;
    `);
    for (let i = 0; i < rawGlobalAsyncTracks.numRecords; i++) {
      const name = rawGlobalAsyncTracks.columns[0].stringValues![i];
      const rawTrackIds = rawGlobalAsyncTracks.columns[1].stringValues![i];
      const trackIds = rawTrackIds.split(',').map(v => Number(v));
      const maxDepth = +rawGlobalAsyncTracks.columns[2].longValues![i];
      const track = {
        engineId: this.engineId,
        kind: ASYNC_SLICE_TRACK_KIND,
        trackGroup: SCROLLING_TRACK_GROUP,
        name,
        config: {
          maxDepth,
          trackIds,
        },
      };
      tracksToAdd.push(track);
    }

    const upidToProcessTracks = new Map();
    const rawProcessTracks = await engine.query(`
      SELECT
        pt.upid,
        pt.name,
        pt.track_ids,
        MAX(experimental_slice_layout.layout_depth) as max_depth
      FROM (
        SELECT upid, name, GROUP_CONCAT(process_track.id) AS track_ids
        FROM process_track GROUP BY upid, name
      ) AS pt CROSS JOIN experimental_slice_layout
      WHERE pt.track_ids = experimental_slice_layout.filter_track_ids
      GROUP BY pt.track_ids;
    `);
    for (let i = 0; i < rawProcessTracks.numRecords; i++) {
      const upid = +rawProcessTracks.columns[0].longValues![i];
      const name = rawProcessTracks.columns[1].stringValues![i];
      const rawTrackIds = rawProcessTracks.columns[2].stringValues![i];
      const trackIds = rawTrackIds.split(',').map(v => Number(v));
      const maxDepth = +rawProcessTracks.columns[3].longValues![i];
      const track = {
        engineId: this.engineId,
        kind: 'AsyncSliceTrack',
        name,
        config: {
          maxDepth,
          trackIds,
        },
      };
      const tracks = upidToProcessTracks.get(upid);
      if (tracks) {
        tracks.push(track);
      } else {
        upidToProcessTracks.set(upid, [track]);
      }
    }

    const heapProfiles = await engine.query(`
      select distinct(upid) from heap_profile_allocation
      union
      select distinct(upid) from heap_graph_object`);

    const heapUpids: Set<number> = new Set();
    for (let i = 0; i < heapProfiles.numRecords; i++) {
      const upid = heapProfiles.columns[0].longValues![i];
      heapUpids.add(+upid);
    }

    const maxGpuFreq = await engine.query(`
      select max(value)
      from counter c
      inner join gpu_counter_track t on c.track_id = t.id
      where name = 'gpufreq';
    `);

    for (let gpu = 0; gpu < numGpus; gpu++) {
      // Only add a gpu freq track if we have
      // gpu freq data.
      const freqExists = await engine.query(`
        select id
        from gpu_counter_track
        where name = 'gpufreq' and gpu_id = ${gpu}
        limit 1;
      `);
      if (freqExists.numRecords > 0) {
        tracksToAdd.push({
          engineId: this.engineId,
          kind: COUNTER_TRACK_KIND,
          name: `Gpu ${gpu} Frequency`,
          trackGroup: SCROLLING_TRACK_GROUP,
          config: {
            trackId: +freqExists.columns[0].longValues![0],
            maximumValue: +maxGpuFreq.columns[0].doubleValues![0],
          }
        });
      }
    }

    // Add global or GPU counter tracks that are not bound to any pid/tid.
    const globalCounters = await engine.query(`
      select name, id
      from counter_track
      where type = 'counter_track'
      union
      select name, id
      from gpu_counter_track
      where name != 'gpufreq'
    `);
    for (let i = 0; i < globalCounters.numRecords; i++) {
      const name = globalCounters.columns[0].stringValues![i];
      const trackId = +globalCounters.columns[1].longValues![i];
      tracksToAdd.push({
        engineId: this.engineId,
        kind: COUNTER_TRACK_KIND,
        name,
        trackGroup: SCROLLING_TRACK_GROUP,
        config: {
          name,
          trackId,
        }
      });
    }

    interface CounterTrack {
      name: string;
      trackId: number;
      startTs?: number;
      endTs?: number;
    }

    const counterUtids = new Map<number, CounterTrack[]>();
    const threadCounters = await engine.query(`
      select thread_counter_track.name, utid, thread_counter_track.id,
      start_ts, end_ts from thread_counter_track join thread using(utid)
      where thread_counter_track.name not in ('time_in_state')
    `);
    for (let i = 0; i < threadCounters.numRecords; i++) {
      const name = threadCounters.columns[0].stringValues![i];
      const utid = +threadCounters.columns[1].longValues![i];
      const trackId = +threadCounters.columns[2].longValues![i];
      let startTs = undefined;
      let endTs = undefined;
      if (!threadCounters.columns[3].isNulls![i]) {
        startTs = +threadCounters.columns[3].longValues![i] / 1e9;
      }
      if (!threadCounters.columns[4].isNulls![i]) {
        endTs = +threadCounters.columns[4].longValues![i] / 1e9;
      }

      const track: CounterTrack = {name, trackId, startTs, endTs};
      const el = counterUtids.get(utid);
      if (el === undefined) {
        counterUtids.set(utid, [track]);
      } else {
        el.push(track);
      }
    }

    const counterUpids = new Map<number, CounterTrack[]>();
    const processCounters = await engine.query(`
      select process_counter_track.name, upid, process_counter_track.id,
      start_ts, end_ts from process_counter_track join process using(upid)
    `);
    for (let i = 0; i < processCounters.numRecords; i++) {
      const name = processCounters.columns[0].stringValues![i];
      const upid = +processCounters.columns[1].longValues![i];
      const trackId = +processCounters.columns[2].longValues![i];
      let startTs = undefined;
      let endTs = undefined;
      if (!processCounters.columns[3].isNulls![i]) {
        startTs = +processCounters.columns[3].longValues![i] / 1e9;
      }
      if (!processCounters.columns[4].isNulls![i]) {
        endTs = +processCounters.columns[4].longValues![i] / 1e9;
      }

      const track: CounterTrack = {name, trackId, startTs, endTs};
      const el = counterUpids.get(upid);
      if (el === undefined) {
        counterUpids.set(upid, [track]);
      } else {
        el.push(track);
      }
    }

    // Local experiments shows getting maxDepth separately is ~2x faster than
    // joining with threads and processes.
    const maxDepthQuery = await engine.query(`
          select thread_track.utid, thread_track.id, max(depth) as maxDepth
          from slice
          inner join thread_track on slice.track_id = thread_track.id
          group by thread_track.id
        `);

    const utidToThreadTrack = new Map<number, ThreadSliceTrack>();
    for (let i = 0; i < maxDepthQuery.numRecords; i++) {
      const utid = maxDepthQuery.columns[0].longValues![i];
      const trackId = maxDepthQuery.columns[1].longValues![i];
      const maxDepth = maxDepthQuery.columns[2].longValues![i];
      utidToThreadTrack.set(utid, {maxDepth, trackId});
    }

    // For backwards compatability with older TP versions where
    // android_thread_time_in_state_event table does not exists.
    // TODO: remove once the track mega-query is improved.
    const exists = await engine.query(
        `select name from sqlite_master where type='table' and
         name='android_thread_time_in_state_event'`);
    if (exists.numRecords === 0) {
      await engine.query(`create view android_thread_time_in_state_event as
          select null as upid, null as value where 0`);
    }

    // Return all threads
    // sorted by:
    //  total cpu time *for the whole parent process*
    //  upid
    //  utid
    const threadQuery = await engine.query(`
        select
          utid,
          tid,
          upid,
          pid,
          thread.name as threadName,
          process.name as processName,
          total_dur as totalDur,
          ifnull(has_sched, false) as hasSched,
          ifnull(has_cpu_samples, false) as hasCpuSamples
        from
          thread
          left join (select utid, count(1), true as has_sched
              from sched group by utid
          ) using(utid)
          left join (select utid, count(1), true as has_cpu_samples
              from cpu_profile_stack_sample group by utid
          ) using(utid)
          left join process using(upid)
          left join (select upid, sum(dur) as total_dur
              from sched join thread using(utid)
              group by upid
            ) using(upid)
          left join (select upid, sum(value) as total_cycles
              from android_thread_time_in_state_event
              group by upid
            ) using(upid)
        where utid != 0
        group by utid, upid
        order by total_dur desc, total_cycles desc, upid, utid`);

    const upidToUuid = new Map<number, string>();
    const utidToUuid = new Map<number, string>();
    const addTrackGroupActions: DeferredAction[] = [];

    for (const row of rawQueryToRows(threadQuery, {
           utid: NUM,
           upid: NUM_NULL,
           tid: NUM_NULL,
           pid: NUM_NULL,
           threadName: STR_NULL,
           processName: STR_NULL,
           totalDur: NUM_NULL,
           hasSched: NUM,
           hasCpuSamples: NUM,
         })) {
      const utid = row.utid;
      const tid = row.tid;
      const upid = row.upid;
      const pid = row.pid;
      const threadName = row.threadName;
      const processName = row.processName;
      const hasSchedEvents = !!row.totalDur;
      const threadHasSched = !!row.hasSched;
      const threadHasCpuSamples = !!row.hasCpuSamples;

      const threadTrack =
          utid === null ? undefined : utidToThreadTrack.get(utid);
      if (threadTrack === undefined &&
          (upid === null || counterUpids.get(upid) === undefined) &&
          counterUtids.get(utid) === undefined && !threadHasSched &&
          (upid === null || upid !== null && !heapUpids.has(upid))) {
        continue;
      }

      // Group by upid if present else by utid.
      let pUuid = upid === null ? utidToUuid.get(utid) : upidToUuid.get(upid);
      // These should only happen once for each track group.
      if (pUuid === undefined) {
        pUuid = uuidv4();
        const summaryTrackId = uuidv4();
        if (upid === null) {
          utidToUuid.set(utid, pUuid);
        } else {
          upidToUuid.set(upid, pUuid);
        }

        const pidForColor = pid || tid || upid || utid || 0;
        const kind = hasSchedEvents ? PROCESS_SCHEDULING_TRACK_KIND :
                                      PROCESS_SUMMARY_TRACK;

        tracksToAdd.push({
          id: summaryTrackId,
          engineId: this.engineId,
          kind,
          name: `${upid === null ? tid : pid} summary`,
          config: {pidForColor, upid, utid},
        });

        const name =
            getTrackName({utid, processName, pid, threadName, tid, upid});
        const addTrackGroup = Actions.addTrackGroup({
          engineId: this.engineId,
          summaryTrackId,
          name,
          id: pUuid,
          collapsed: !(upid !== null && heapUpids.has(upid)),
        });

        // If the track group contains a heap profile, it should be before all
        // other processes.
        if (upid !== null && heapUpids.has(upid)) {
          addTrackGroupActions.unshift(addTrackGroup);
        } else {
          addTrackGroupActions.push(addTrackGroup);
        }

        if (upid !== null) {
          if (heapUpids.has(upid)) {
            tracksToAdd.push({
              engineId: this.engineId,
              kind: HEAP_PROFILE_TRACK_KIND,
              name: `Heap Profile`,
              trackGroup: pUuid,
              config: {upid}
            });
          }

          const counterNames = counterUpids.get(upid);
          if (counterNames !== undefined) {
            counterNames.forEach(element => {
              tracksToAdd.push({
                engineId: this.engineId,
                kind: 'CounterTrack',
                name: element.name,
                trackGroup: pUuid,
                config: {
                  name: element.name,
                  trackId: element.trackId,
                  startTs: element.startTs,
                  endTs: element.endTs,
                }
              });
            });
          }

          if (upidToProcessTracks.has(upid)) {
            for (const track of upidToProcessTracks.get(upid)) {
              tracksToAdd.push(Object.assign(track, {trackGroup: pUuid}));
            }
          }
        }
      }
      const counterThreadNames = counterUtids.get(utid);
      if (counterThreadNames !== undefined) {
        counterThreadNames.forEach(element => {
          tracksToAdd.push({
            engineId: this.engineId,
            kind: 'CounterTrack',
            name: `${threadName} (${element.name})`,
            trackGroup: pUuid,
            config: {
              name: element.name,
              trackId: element.trackId,
              startTs: element.startTs,
              endTs: element.endTs,
            }
          });
        });
      }

      if (threadHasCpuSamples) {
        tracksToAdd.push({
          engineId: this.engineId,
          kind: CPU_PROFILE_TRACK_KIND,
          name: `${threadName} (CPU Stack Samples)`,
          trackGroup: pUuid,
          config: {utid},
        });
      }

      if (threadHasSched) {
        tracksToAdd.push({
          engineId: this.engineId,
          kind: THREAD_STATE_TRACK_KIND,
          name: getTrackName({utid, tid, threadName}),
          trackGroup: pUuid,
          config: {utid}
        });
      }

      if (threadTrack !== undefined) {
        tracksToAdd.push({
          engineId: this.engineId,
          kind: SLICE_TRACK_KIND,
          name: getTrackName({utid, tid, threadName}),
          trackGroup: pUuid,
          config:
              {maxDepth: threadTrack.maxDepth, trackId: threadTrack.trackId},
        });
      }
    }

    const logCount = await engine.query(`select count(1) from android_logs`);
    if (logCount.columns[0].longValues![0] > 0) {
      tracksToAdd.push({
        engineId: this.engineId,
        kind: ANDROID_LOGS_TRACK_KIND,
        name: 'Android logs',
        trackGroup: SCROLLING_TRACK_GROUP,
        config: {}
      });
    }

    const annotationSliceRows = await engine.query(`
      SELECT id, name, upid FROM annotation_slice_track`);
    for (let i = 0; i < annotationSliceRows.numRecords; i++) {
      const id = annotationSliceRows.columns[0].longValues![i];
      const name = annotationSliceRows.columns[1].stringValues![i];
      const upid = annotationSliceRows.columns[2].longValues![i];
      tracksToAdd.push({
        engineId: this.engineId,
        kind: SLICE_TRACK_KIND,
        name,
        trackGroup: upid === 0 ? SCROLLING_TRACK_GROUP : upidToUuid.get(upid),
        config: {
          maxDepth: 0,
          namespace: 'annotation',
          trackId: id,
        },
      });
    }

    const annotationCounterRows = await engine.query(`
      SELECT id, name, upid, min_value, max_value
      FROM annotation_counter_track`);
    for (let i = 0; i < annotationCounterRows.numRecords; i++) {
      const id = annotationCounterRows.columns[0].longValues![i];
      const name = annotationCounterRows.columns[1].stringValues![i];
      const upid = annotationCounterRows.columns[2].longValues![i];
      const minimumValue = annotationCounterRows.columns[3].isNulls![i] ?
          undefined :
          annotationCounterRows.columns[3].doubleValues![i];
      const maximumValue = annotationCounterRows.columns[4].isNulls![i] ?
          undefined :
          annotationCounterRows.columns[4].doubleValues![i];
      tracksToAdd.push({
        engineId: this.engineId,
        kind: 'CounterTrack',
        name,
        trackGroup: upid === 0 ? SCROLLING_TRACK_GROUP : upidToUuid.get(upid),
        config: {
          name,
          namespace: 'annotation',
          trackId: id,
          minimumValue,
          maximumValue,
        }
      });
    }

    addTrackGroupActions.push(Actions.addTracks({tracks: tracksToAdd}));
    globals.dispatchMultiple(addTrackGroupActions);
  }

  private async listThreads() {
    this.updateStatus('Reading thread list');
    const sqlQuery = `select utid, tid, pid, thread.name,
        ifnull(
          case when length(process.name) > 0 then process.name else null end,
          thread.name),
        process.cmdline
        from (select * from thread order by upid) as thread
        left join (select * from process order by upid) as process
        using(upid)`;
    const threadRows = await assertExists(this.engine).query(sqlQuery);
    const threads: ThreadDesc[] = [];
    for (let i = 0; i < threadRows.numRecords; i++) {
      const utid = threadRows.columns[0].longValues![i];
      const tid = threadRows.columns[1].longValues![i];
      const pid = threadRows.columns[2].longValues![i];
      const threadName = threadRows.columns[3].stringValues![i];
      const procName = threadRows.columns[4].stringValues![i];
      const cmdline = threadRows.columns[5].stringValues![i];
      threads.push({utid, tid, threadName, pid, procName, cmdline});
    }  // for (record ...)
    globals.publish('Threads', threads);
  }

  private async loadTimelineOverview(traceTime: TimeSpan) {
    const engine = assertExists<Engine>(this.engine);
    const numSteps = 100;
    const stepSec = traceTime.duration / numSteps;
    let hasSchedOverview = false;
    for (let step = 0; step < numSteps; step++) {
      this.updateStatus(
          'Loading overview ' +
          `${Math.round((step + 1) / numSteps * 1000) / 10}%`);
      const startSec = traceTime.start + step * stepSec;
      const startNs = toNsFloor(startSec);
      const endSec = startSec + stepSec;
      const endNs = toNsCeil(endSec);

      // Sched overview.
      const schedRows = await engine.query(
          `select sum(dur)/${stepSec}/1e9, cpu from sched ` +
          `where ts >= ${startNs} and ts < ${endNs} and utid != 0 ` +
          'group by cpu order by cpu');
      const schedData: {[key: string]: QuantizedLoad} = {};
      for (let i = 0; i < schedRows.numRecords; i++) {
        const load = schedRows.columns[0].doubleValues![i];
        const cpu = schedRows.columns[1].longValues![i];
        schedData[cpu] = {startSec, endSec, load};
        hasSchedOverview = true;
      }  // for (record ...)
      globals.publish('OverviewData', schedData);
    }  // for (step ...)

    if (hasSchedOverview) {
      return;
    }

    // Slices overview.
    const traceStartNs = toNs(traceTime.start);
    const stepSecNs = toNs(stepSec);
    const sliceSummaryQuery = await engine.query(`select
           bucket,
           upid,
           sum(utid_sum) / cast(${stepSecNs} as float) as upid_sum
         from thread
         inner join (
           select
             cast((ts - ${traceStartNs})/${stepSecNs} as int) as bucket,
             sum(dur) as utid_sum,
             utid
           from slice
           inner join thread_track on slice.track_id = thread_track.id
           group by bucket, utid
         ) using(utid)
         group by bucket, upid`);

    const slicesData: {[key: string]: QuantizedLoad[]} = {};
    for (let i = 0; i < sliceSummaryQuery.numRecords; i++) {
      const bucket = sliceSummaryQuery.columns[0].longValues![i];
      const upid = sliceSummaryQuery.columns[1].longValues![i];
      const load = sliceSummaryQuery.columns[2].doubleValues![i];

      const startSec = traceTime.start + stepSec * bucket;
      const endSec = startSec + stepSec;

      const upidStr = upid.toString();
      let loadArray = slicesData[upidStr];
      if (loadArray === undefined) {
        loadArray = slicesData[upidStr] = [];
      }
      loadArray.push({startSec, endSec, load});
    }
    globals.publish('OverviewData', slicesData);
  }

  async initialiseHelperViews() {
    const engine = assertExists<Engine>(this.engine);
    this.updateStatus('Creating views');
    let event = 'sched_waking';
    const waking = await engine.query(
        `select * from instants where name = 'sched_waking' limit 1`);
    if (waking.numRecords === 0) {
      // Only use sched_wakeup if sched_waking is not in the trace.
      event = 'sched_wakeup';
    }
    await engine.query(`create view runnable AS
      select
        ts,
        lead(ts, 1, (select end_ts from trace_bounds))
          OVER(partition by ref order by ts) - ts as dur,
        ref as utid
      from instants
      where name = '${event}'`);

    // Get the first ts for each utid - whether a sched wakeup/waking
    // or sched event.
    await engine.query(`create view first_thread as
      select min(ts) as ts, utid from
      (select min(ts) as ts, utid from runnable group by utid
       UNION
      select min(ts) as ts,utid from sched group by utid)
      group by utid`);

    // Create an entry from first ts to either the first sched_wakeup/waking
    // or to the end if there are no sched wakeup/ings. This means we will
    // show all information we have even with no sched_wakeup/waking events.
    await engine.query(`create view fill as
      select first_thread.ts as ts,
      coalesce(min(runnable.ts), (select end_ts from trace_bounds)) -
      first_thread.ts as dur,
      first_thread.utid as utid
      from first_thread
      LEFT JOIN runnable using(utid) group by utid`);

    await engine.query(`create view full_runnable as
        select * from runnable UNION
        select * from fill`);

    await engine.query(`create virtual table thread_span
        using span_left_join(
          full_runnable partitioned utid,
          sched partitioned utid)`);

    this.updateStatus('Creating thread state table');
    // For performance reasons we need to create a table here.
    // Once b/145350531 is fixed this should be able to revert to a
    // view and we can recover the extra memory use.
    await engine.query(`create table thread_state as
      select ts, dur, utid, cpu,
      case when end_state is not null then 'Running'
      when lag(end_state) over ordered is not null
      then lag(end_state) over ordered else 'R'
      end as state
      from thread_span window ordered as
      (partition by utid order by ts)`);

    this.updateStatus('Creating thread state index');
    await engine.query(`create index utid_index on thread_state(utid)`);

    this.updateStatus('Creating annotation counter track table');
    // Create the helper tables for all the annotations related data.
    // NULL in min/max means "figure it out per track in the usual way".
    await engine.query(`
      CREATE TABLE annotation_counter_track(
        id INTEGER PRIMARY KEY,
        name STRING,
        __metric_name STRING,
        upid INTEGER,
        min_value DOUBLE,
        max_value DOUBLE
      );
    `);
    this.updateStatus('Creating annotation slice track table');
    await engine.query(`
      CREATE TABLE annotation_slice_track(
        id INTEGER PRIMARY KEY,
        name STRING,
        __metric_name STRING,
        upid INTEGER
      );
    `);

    this.updateStatus('Creating annotation counter table');
    await engine.query(`
      CREATE TABLE annotation_counter(
        id BIG INT,
        track_id INT,
        ts BIG INT,
        value DOUBLE,
        PRIMARY KEY (track_id, ts)
      ) WITHOUT ROWID;
    `);
    this.updateStatus('Creating annotation slice table');
    await engine.query(`
      CREATE TABLE annotation_slice(
        id INTEGER PRIMARY KEY,
        track_id INT,
        ts BIG INT,
        dur BIG INT,
        depth INT,
        cat STRING,
        name STRING,
        UNIQUE(track_id, ts)
      );
    `);

    for (const metric
             of ['android_startup',
                 'android_ion',
                 'android_thread_time_in_state',
                 'android_surfaceflinger',
                 'android_batt']) {
      this.updateStatus(`Computing ${metric} metric`);
      // We don't care about the actual result of metric here as we are just
      // interested in the annotation tracks.
      const metricResult = await engine.computeMetric([metric]);
      assertTrue(metricResult.error.length === 0);

      const exists = await engine.query(
          `SELECT name FROM sqlite_master WHERE type='table' AND name='${
              metric}_event'`);
      if (exists.numRecords === 0) return;

      this.updateStatus(`Inserting data for ${metric} metric`);
      const result = await engine.query(`
        SELECT * FROM ${metric}_event LIMIT 1`);

      const hasSliceName =
          result.columnDescriptors.some(x => x.name === 'slice_name');
      const hasDur = result.columnDescriptors.some(x => x.name === 'dur');
      const hasUpid = result.columnDescriptors.some(x => x.name === 'upid');

      const upidColumnSelect = hasUpid ? 'upid' : '0 AS upid';
      const upidColumnWhere = hasUpid ? 'upid' : '0';
      if (hasSliceName && hasDur) {
        await engine.query(`
          INSERT INTO annotation_slice_track(name, __metric_name, upid)
          SELECT DISTINCT
            track_name,
            '${metric}' as metric_name,
            ${upidColumnSelect}
          FROM ${metric}_event
          WHERE track_type = 'slice'
        `);
        await engine.query(`
          INSERT INTO annotation_slice(track_id, ts, dur, depth, cat, name)
          SELECT
            t.id AS track_id,
            ts,
            dur,
            0 AS depth,
            a.track_name as cat,
            slice_name AS name
          FROM ${metric}_event a
          JOIN annotation_slice_track t
          ON a.track_name = t.name AND t.__metric_name = '${metric}'
          ORDER BY t.id, ts
        `);
      }

      const hasValue = result.columnDescriptors.some(x => x.name === 'value');
      if (hasValue) {
        const minMax = await engine.query(`
          SELECT MIN(value) as min_value, MAX(value) as max_value
          FROM ${metric}_event
          WHERE ${upidColumnWhere} != 0`);
        const min = minMax.columns[0].longValues![0];
        const max = minMax.columns[1].longValues![0];
        await engine.query(`
          INSERT INTO annotation_counter_track(
            name, __metric_name, min_value, max_value, upid)
          SELECT DISTINCT
            track_name,
            '${metric}' as metric_name,
            CASE ${upidColumnWhere} WHEN 0 THEN NULL ELSE ${min} END,
            CASE ${upidColumnWhere} WHEN 0 THEN NULL ELSE ${max} END,
            ${upidColumnSelect}
          FROM ${metric}_event
          WHERE track_type = 'counter'
        `);
        await engine.query(`
          INSERT INTO annotation_counter(id, track_id, ts, value)
          SELECT
            -1 as id,
            t.id AS track_id,
            ts,
            value
          FROM ${metric}_event a
          JOIN annotation_counter_track t
          ON a.track_name = t.name AND t.__metric_name = '${metric}'
          ORDER BY t.id, ts
        `);
      }
    }
  }

  private updateStatus(msg: string): void {
    globals.dispatch(Actions.updateStatus({
      msg,
      timestamp: Date.now() / 1000,
    }));
  }
}

function getTrackName(args: Partial<{
  utid: number,
  processName: string | null,
  pid: number | null,
  threadName: string | null,
  tid: number | null,
  upid: number | null
}>) {
  const {upid, utid, processName, threadName, pid, tid} = args;

  const hasUpid = upid !== undefined && upid !== null;
  const hasUtid = utid !== undefined && utid !== null;
  const hasProcessName = processName !== undefined && processName !== null;
  const hasThreadName = threadName !== undefined && threadName !== null;
  const hasTid = tid !== undefined && tid !== null;
  const hasPid = pid !== undefined && pid !== null;

  if (hasUpid && hasPid && hasProcessName) {
    return `${processName} ${pid}`;
  } else if (hasUpid && hasPid) {
    return `Process ${pid}`;
  } else if (hasThreadName && hasTid) {
    return `${threadName} ${tid}`;
  } else if (hasTid) {
    return `Thread ${tid}`;
  } else if (hasUpid) {
    return `upid: ${upid}`;
  } else if (hasUtid) {
    return `utid: ${utid}`;
  }
  return 'Unknown';
}
