// 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 './query_table.scss';
import type {Engine} from '../../trace_processor/engine';
import type {Row} from '../../trace_processor/query_result';

export interface QueryResponse {
  query: string;
  error?: string;
  totalRowCount: number;
  durationMs: number;
  columns: string[];
  rows: Row[];
  statementCount: number;
  statementWithOutputCount: number;
  lastStatementSql: string;
}

/**
 * Runs a query and pulls out all the columns into a list of 'row' objects,
 * where each row contains a dictionary of [columnName] -> value.
 *
 * This method will not throw if the query fails, instead the error is populated
 * in the return value.
 *
 * This function is designed to be used with table viewers, where the structure
 * of resulting rows is not known up front. Use engine.query() or
 * engine.tryQuery() and use the iterators if the resulting data is to be
 * processed.
 *
 * @param sqlQuery - The query to evaluate.
 * @param engine - The engine to use to run the query.
 */
export async function runQueryForQueryTable(
  sqlQuery: string,
  engine: Engine,
): Promise<QueryResponse> {
  const startMs = performance.now();

  // TODO(primiano): once the controller thread is gone we should pass down
  // the result objects directly to the frontend, iterate over the result
  // and deal with pagination there. For now we keep the old behavior and
  // truncate to 10k rows.

  const maybeResult = await engine.tryQuery(sqlQuery);

  if (maybeResult.ok) {
    const queryRes = maybeResult.value;

    const rows: Row[] = [];
    const columns = queryRes.columns();
    for (const iter = queryRes.iter({}); iter.valid(); iter.next()) {
      const row: Row = {};
      for (const colName of columns) {
        const value = iter.get(colName);
        row[colName] = value;
      }
      rows.push(row);
    }

    const result: QueryResponse = {
      query: sqlQuery,
      durationMs: queryRes.elapsedTimeMs(),
      error: queryRes.error(),
      totalRowCount: queryRes.numRows(),
      columns,
      rows,
      statementCount: queryRes.statementCount(),
      statementWithOutputCount: queryRes.statementWithOutputCount(),
      lastStatementSql: queryRes.lastStatementSql(),
    };
    return result;
  } else {
    // In the case of a query error we don't want the exception to bubble up
    // as a crash. The |queryRes| object will be populated anyways.
    // queryRes.error() is used to tell if the query errored or not. If it
    // errored, the frontend will show a graceful message instead.
    return {
      query: sqlQuery,
      durationMs: performance.now() - startMs,
      error: maybeResult.error,
      totalRowCount: 0,
      columns: [],
      rows: [],
      statementCount: 0,
      statementWithOutputCount: 0,
      lastStatementSql: '',
    };
  }
}
