// Copyright (C) 2023 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 {sqliteString} from '../../base/string_utils';

import {
  ArgSetIdColumn,
  dependendentColumns,
  DisplayConfig,
  RegularSqlTableColumn,
} from './table_description';

// This file contains the defintions of different column types that can be
// displayed in the table viewer.

export interface Column {
  // SQL expression calculating the value of this column.
  expression: string;
  // Unique name for this column.
  // The relevant bit of SQL fetching this column will be ${expression} as
  // ${alias}.
  alias: string;
  // Title to be displayed in the table header.
  title: string;
  // How the value of this column should be rendered.
  display?: DisplayConfig;
}

export function columnFromSqlTableColumn(c: RegularSqlTableColumn): Column {
  return {
    expression: c.name,
    alias: c.name,
    title: c.title || c.name,
    display: c.display,
  };
}

export function argColumn(
  tableName: string,
  c: ArgSetIdColumn,
  argName: string,
): Column {
  const escape = (name: string) => name.replace(/[^A-Za-z0-9]/g, '_');
  return {
    expression: `extract_arg(${tableName}.${c.name}, ${sqliteString(argName)})`,
    alias: `_arg_${c.name}_${escape(argName)}`,
    title: `${c.title ?? c.name} ${argName}`,
  };
}

// A single instruction from a select part of the SQL statement, i.e.
// select `expression` as `alias`.
export type SqlProjection = {
  expression: string;
  alias: string;
};

export function formatSqlProjection(p: SqlProjection): string {
  return `${p.expression} as ${p.alias}`;
}

// Returns a list of projections (i.e. parts of the SELECT clause) that should
// be added to the query fetching the data to be able to display the given
// column (e.g. `foo` or `f(bar) as baz`).
// Some table columns are backed by multiple SQL columns (e.g. slice_id is
// backed by id, ts, dur and track_id), so we need to return a list.
export function sqlProjectionsForColumn(column: Column): SqlProjection[] {
  const result: SqlProjection[] = [
    {
      expression: column.expression,
      alias: column.alias,
    },
  ];
  for (const dependency of dependendentColumns(column.display)) {
    result.push({
      expression: dependency,
      alias: dependency,
    });
  }
  return result;
}
