/*
 * 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 {Actions} from '../common/actions';
import {DEFAULT_CHANNEL, getCurrentChannel} from '../common/channels';
import {Engine} from '../common/engine';
import {featureFlags} from '../common/feature_flags';
import {ColumnType, STR} from '../common/query_result';
import {
  AreaSelection,
  PivotTableQuery,
  PivotTableQueryMetadata,
  PivotTableResult,
  PivotTableState,
} from '../common/state';
import {globals} from '../frontend/globals';
import {
  aggregationIndex,
  generateQueryFromState,
} from '../frontend/pivot_table_query_generator';
import {Aggregation, PivotTree} from '../frontend/pivot_table_types';

import {Controller} from './controller';

export const PIVOT_TABLE_REDUX_FLAG = featureFlags.register({
  id: 'pivotTable',
  name: 'Pivot tables V2',
  description: 'Second version of pivot table',
  // Enabled in canary and autopush by default.
  defaultValue: getCurrentChannel() !== DEFAULT_CHANNEL,
});

function expectNumber(value: ColumnType): number {
  if (typeof value === 'number') {
    return value;
  } else if (typeof value === 'bigint') {
    return Number(value);
  }
  throw new Error(`number or bigint was expected, got ${typeof value}`);
}

// Auxiliary class to build the tree from query response.
export class PivotTableTreeBuilder {
  private readonly root: PivotTree;
  queryMetadata: PivotTableQueryMetadata;

  get pivotColumnsCount(): number {
    return this.queryMetadata.pivotColumns.length;
  }

  get aggregateColumns(): Aggregation[] {
    return this.queryMetadata.aggregationColumns;
  }

  constructor(queryMetadata: PivotTableQueryMetadata, firstRow: ColumnType[]) {
    this.queryMetadata = queryMetadata;
    this.root = this.createNode(firstRow);
    let tree = this.root;
    for (let i = 0; i + 1 < this.pivotColumnsCount; i++) {
      const value = firstRow[i];
      tree = this.insertChild(tree, value, this.createNode(firstRow));
    }
    tree.rows.push(firstRow);
  }

  // Add incoming row to the tree being built.
  ingestRow(row: ColumnType[]) {
    let tree = this.root;
    this.updateAggregates(tree, row);
    for (let i = 0; i + 1 < this.pivotColumnsCount; i++) {
      const nextTree = tree.children.get(row[i]);
      if (nextTree === undefined) {
        // Insert the new node into the tree, and make variable `tree` point
        // to the newly created node.
        tree = this.insertChild(tree, row[i], this.createNode(row));
      } else {
        this.updateAggregates(nextTree, row);
        tree = nextTree;
      }
    }
    tree.rows.push(row);
  }

  build(): PivotTree {
    return this.root;
  }

  updateAggregates(tree: PivotTree, row: ColumnType[]) {
    const countIndex = this.queryMetadata.countIndex;
    const treeCount =
        countIndex >= 0 ? expectNumber(tree.aggregates[countIndex]) : 0;
    const rowCount = countIndex >= 0 ?
        expectNumber(
            row[aggregationIndex(this.pivotColumnsCount, countIndex)]) :
        0;

    for (let i = 0; i < this.aggregateColumns.length; i++) {
      const agg = this.aggregateColumns[i];

      const currAgg = tree.aggregates[i];
      const childAgg = row[aggregationIndex(this.pivotColumnsCount, i)];
      if (typeof currAgg === 'number' && typeof childAgg === 'number') {
        switch (agg.aggregationFunction) {
          case 'SUM':
          case 'COUNT':
            tree.aggregates[i] = currAgg + childAgg;
            break;
          case 'MAX':
            tree.aggregates[i] = Math.max(currAgg, childAgg);
            break;
          case 'MIN':
            tree.aggregates[i] = Math.min(currAgg, childAgg);
            break;
          case 'AVG': {
            const currSum = currAgg * treeCount;
            const addSum = childAgg * rowCount;
            tree.aggregates[i] = (currSum + addSum) / (treeCount + rowCount);
            break;
          }
        }
      }
    }
    tree.aggregates[this.aggregateColumns.length] = treeCount + rowCount;
  }

  // Helper method that inserts child node into the tree and returns it, used
  // for more concise modification of local variable pointing to the current
  // node being built.
  insertChild(tree: PivotTree, key: ColumnType, child: PivotTree): PivotTree {
    tree.children.set(key, child);

    return child;
  }

  // Initialize PivotTree from a row.
  createNode(row: ColumnType[]): PivotTree {
    const aggregates = [];

    for (let j = 0; j < this.aggregateColumns.length; j++) {
      aggregates.push(row[aggregationIndex(this.pivotColumnsCount, j)]);
    }
    aggregates.push(row[aggregationIndex(
        this.pivotColumnsCount, this.aggregateColumns.length)]);

    return {
      isCollapsed: false,
      children: new Map(),
      aggregates,
      rows: [],
    };
  }
}

function createEmptyQueryResult(metadata: PivotTableQueryMetadata):
    PivotTableResult {
  return {
    tree: {
      aggregates: [],
      isCollapsed: false,
      children: new Map(),
      rows: [],
    },
    metadata,
  };
}

// Controller responsible for showing the panel with pivot table, as well as
// executing its queries and post-processing query results.
export class PivotTableController extends Controller<{}> {
  static detailsCount = 0;
  engine: Engine;
  lastQueryAreaId = '';
  lastQueryAreaTracks = new Set<string>();
  requestedArgumentNames = false;

  constructor(args: {engine: Engine}) {
    super({});
    this.engine = args.engine;
  }

  sameTracks(tracks: Set<string>) {
    if (this.lastQueryAreaTracks.size !== tracks.size) {
      return false;
    }

    // ES6 Set does not have .every method, only Array does.
    for (const track in tracks) {
      if (!this.lastQueryAreaTracks.has(track)) {
        return false;
      }
    }

    return true;
  }

  shouldRerun(state: PivotTableState, selection: AreaSelection) {
    if (state.selectionArea === undefined) {
      return false;
    }

    const newTracks = new Set(globals.state.areas[selection.areaId].tracks);
    if (this.lastQueryAreaId !== state.selectionArea.areaId ||
        !this.sameTracks(newTracks)) {
      this.lastQueryAreaId = state.selectionArea.areaId;
      this.lastQueryAreaTracks = newTracks;
      return true;
    }
    return false;
  }

  async processQuery(query: PivotTableQuery) {
    const result = await this.engine.query(query.text);
    try {
      await result.waitAllRows();
    } catch {
      // waitAllRows() frequently throws an exception, which is ignored in
      // its other calls, so it's ignored here as well.
    }

    const columns = result.columns();

    const it = result.iter({});
    function nextRow(): ColumnType[] {
      const row: ColumnType[] = [];
      for (const column of columns) {
        row.push(it.get(column));
      }
      it.next();
      return row;
    }

    if (!it.valid()) {
      // Iterator is invalid after creation; means that there are no rows
      // satisfying filtering criteria. Return an empty tree.
      globals.dispatch(Actions.setPivotStateQueryResult(
          {queryResult: createEmptyQueryResult(query.metadata)}));
      return;
    }

    const treeBuilder = new PivotTableTreeBuilder(query.metadata, nextRow());
    while (it.valid()) {
      treeBuilder.ingestRow(nextRow());
    }

    globals.dispatch(Actions.setPivotStateQueryResult(
        {queryResult: {tree: treeBuilder.build(), metadata: query.metadata}}));
    globals.dispatch(Actions.setCurrentTab({tab: 'pivot_table'}));
  }

  async requestArgumentNames() {
    this.requestedArgumentNames = true;
    const result = await this.engine.query(`
      select distinct flat_key from args
    `);
    const it = result.iter({flat_key: STR});

    const argumentNames = [];
    while (it.valid()) {
      argumentNames.push(it.flat_key);
      it.next();
    }

    globals.dispatch(Actions.setPivotTableArgumentNames({argumentNames}));
  }


  run() {
    if (!PIVOT_TABLE_REDUX_FLAG.get()) {
      return;
    }

    if (!this.requestedArgumentNames) {
      this.requestArgumentNames();
    }

    const pivotTableState = globals.state.nonSerializableState.pivotTable;
    const selection = globals.state.currentSelection;

    if (pivotTableState.queryRequested ||
        (selection !== null && selection.kind === 'AREA' &&
         this.shouldRerun(pivotTableState, selection))) {
      globals.dispatch(
          Actions.setPivotTableQueryRequested({queryRequested: false}));
      // Need to re-run the existing query, clear the current result.
      globals.dispatch(Actions.setPivotStateQueryResult({queryResult: null}));
      this.processQuery(generateQueryFromState(pivotTableState));
    }

    if (selection !== null && selection.kind === 'AREA' &&
        (pivotTableState.selectionArea === undefined ||
         pivotTableState.selectionArea.areaId !== selection.areaId)) {
      globals.dispatch(Actions.togglePivotTable({areaId: selection.areaId}));
    }
  }
}
