// 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 {EngineProxy} from './engine';
import {Row} from './query_result';

const MAX_DISPLAY_ROWS = 10000;

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

export interface QueryRunParams {
  // If true, replaces nulls with "NULL" string. Default is true.
  convertNullsToString?: boolean;
}

export async function runQuery(
    sqlQuery: string, engine: EngineProxy, params?: QueryRunParams):
    Promise<QueryResponse> {
  const startMs = performance.now();
  const queryRes = engine.query(sqlQuery);

  // 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.

  try {
    await queryRes.waitAllRows();
  } catch {
    // 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.
  }

  const convertNullsToString = params?.convertNullsToString ?? true;

  const durationMs = performance.now() - startMs;
  const rows: Row[] = [];
  const columns = queryRes.columns();
  let numRows = 0;
  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 === null && convertNullsToString ? 'NULL' : value;
    }
    rows.push(row);
    if (++numRows >= MAX_DISPLAY_ROWS) break;
  }

  const result: QueryResponse = {
    query: sqlQuery,
    durationMs,
    error: queryRes.error(),
    totalRowCount: queryRes.numRows(),
    columns,
    rows,
    statementCount: queryRes.statementCount(),
    statementWithOutputCount: queryRes.statementWithOutputCount(),
    lastStatementSql: queryRes.lastStatementSql(),
  };
  return result;
}
