// Copyright (C) 2020 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 {Engine} from '../common/engine';
import {slowlyCountRows} from '../common/query_iterator';
import {CallsiteInfo, CpuProfileSampleSelection} from '../common/state';
import {CpuProfileDetails} from '../frontend/globals';

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

export interface CpuProfileControllerArgs {
  engine: Engine;
}

export class CpuProfileController extends Controller<'main'> {
  private lastSelectedSample?: CpuProfileSampleSelection;
  private requestingData = false;
  private queuedRunRequest = false;

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

  run() {
    const selection = globals.state.currentSelection;
    if (!selection || selection.kind !== 'CPU_PROFILE_SAMPLE') {
      return;
    }

    const selectedSample = selection as CpuProfileSampleSelection;
    if (!this.shouldRequestData(selectedSample)) {
      return;
    }

    if (this.requestingData) {
      this.queuedRunRequest = true;
      return;
    }

    this.requestingData = true;
    globals.publish('CpuProfileDetails', {});
    this.lastSelectedSample = this.copyCpuProfileSample(selection);

    this.getSampleData(selectedSample.id)
        .then(sampleData => {
          if (sampleData !== undefined && selectedSample &&
              this.lastSelectedSample &&
              this.lastSelectedSample.id === selectedSample.id) {
            const cpuProfileDetails: CpuProfileDetails = {
              id: selectedSample.id,
              ts: selectedSample.ts,
              utid: selectedSample.utid,
              stack: sampleData,
            };

            globals.publish('CpuProfileDetails', cpuProfileDetails);
          }
        })
        .finally(() => {
          this.requestingData = false;
          if (this.queuedRunRequest) {
            this.queuedRunRequest = false;
            this.run();
          }
        });
  }

  private copyCpuProfileSample(cpuProfileSample: CpuProfileSampleSelection):
      CpuProfileSampleSelection {
    return {
      kind: cpuProfileSample.kind,
      id: cpuProfileSample.id,
      utid: cpuProfileSample.utid,
      ts: cpuProfileSample.ts,
    };
  }

  private shouldRequestData(selection: CpuProfileSampleSelection) {
    return this.lastSelectedSample === undefined ||
        (this.lastSelectedSample !== undefined &&
         (this.lastSelectedSample.id !== selection.id));
  }

  async getSampleData(id: number) {
    const sampleQuery = `SELECT samples.id, frame_name, mapping_name
      FROM cpu_profile_stack_sample AS samples
      LEFT JOIN
        (
          SELECT
            callsite_id,
            position,
            spf.name AS frame_name,
            stack_profile_mapping.name AS mapping_name
          FROM
            (
              WITH
                RECURSIVE
                  callsite_parser(callsite_id, current_id, position)
                  AS (
                    SELECT id, id, 0 FROM stack_profile_callsite
                    UNION
                      SELECT callsite_id, parent_id, position + 1
                      FROM callsite_parser
                      JOIN
                        stack_profile_callsite
                        ON stack_profile_callsite.id = current_id
                      WHERE stack_profile_callsite.depth > 0
                  )
              SELECT *
              FROM callsite_parser
            ) AS flattened_callsite
          LEFT JOIN stack_profile_callsite AS spc
          LEFT JOIN
            (
              SELECT
                spf.id AS id,
                spf.mapping AS mapping,
                IFNULL(
                  (
                    SELECT name
                    FROM stack_profile_symbol symbol
                    WHERE symbol.symbol_set_id = spf.symbol_set_id
                    LIMIT 1
                  ),
                  spf.name
                ) AS name
              FROM stack_profile_frame spf
            ) AS spf
          LEFT JOIN stack_profile_mapping
          WHERE
            flattened_callsite.current_id = spc.id
            AND spc.frame_id = spf.id
            AND spf.mapping = stack_profile_mapping.id
          ORDER BY callsite_id, position
        ) AS frames
        ON samples.callsite_id = frames.callsite_id
      WHERE samples.id = ${id}
      ORDER BY samples.id, frames.position DESC;`;

    const callsites = await this.args.engine.query(sampleQuery);

    if (slowlyCountRows(callsites) < 1) {
      return undefined;
    }

    const sampleData: CallsiteInfo[] = new Array();
    for (let i = 0; i < slowlyCountRows(callsites); i++) {
      const id = +callsites.columns[0].longValues![i];
      const name = callsites.columns[1].stringValues![i];
      const mapping = callsites.columns[2].stringValues![i];

      sampleData.push({
        id,
        totalSize: 0,
        depth: 0,
        parentId: 0,
        name,
        selfSize: 0,
        mapping,
        merged: false,
        highlighted: false
      });
    }

    return sampleData;
  }
}
