// 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 m from 'mithril';

import {isString} from '../../base/object_utils';
import {Icons} from '../../base/semantic_icons';
import {EngineProxy} from '../../trace_processor/engine';
import {Row} from '../../trace_processor/query_result';
import {Anchor} from '../../widgets/anchor';
import {BasicTable} from '../../widgets/basic_table';
import {Button} from '../../widgets/button';
import {MenuDivider, MenuItem, PopupMenu2} from '../../widgets/menu';
import {Spinner} from '../../widgets/spinner';

import {ArgumentSelector} from './argument_selector';
import {argColumn, Column, columnFromSqlTableColumn} from './column';
import {renderCell} from './render_cell';
import {SqlTableState} from './state';
import {isArgSetIdColumn, SqlTableDescription} from './table_description';

export interface SqlTableConfig {
  readonly state: SqlTableState;
}

export class SqlTable implements m.ClassComponent<SqlTableConfig> {
  private readonly table: SqlTableDescription;
  private readonly engine: EngineProxy;

  private state: SqlTableState;

  constructor(vnode: m.Vnode<SqlTableConfig>) {
    this.state = vnode.attrs.state;
    this.table = this.state.table;
    this.engine = this.state.engine;
  }

  renderFilters(): m.Children {
    const filters: m.Child[] = [];
    for (const filter of this.state.getFilters()) {
      const label =
          isString(filter) ? filter : `Arg(${filter.argName}) ${filter.op}`;
      filters.push(m(Button, {
        label,
        icon: 'close',
        onclick: () => {
          this.state.removeFilter(filter);
        },
      }));
    }
    return filters;
  }

  renderAddColumnOptions(addColumn: (column: Column) => void): m.Children {
    // We do not want to add columns which already exist, so we track the
    // columns which we are already showing here.
    // TODO(altimin): Theoretically a single table can have two different
    // arg_set_ids, so we should track (arg_set_id_column, arg_name) pairs here.
    const existingColumns = new Set<string>();

    for (const column of this.state.getSelectedColumns()) {
      existingColumns.add(column.alias);
    }

    const result = [];
    for (const column of this.table.columns) {
      if (existingColumns.has(column.name)) continue;
      if (isArgSetIdColumn(column)) {
        result.push(
          m(MenuItem,
            {
              label: column.name,
            },
            m(ArgumentSelector, {
              engine: this.engine,
              argSetId: column,
              tableName: this.table.name,
              constraints: this.state.getQueryConstraints(),
              alreadySelectedColumns: existingColumns,
              onArgumentSelected: (argument: string) => {
                addColumn(argColumn(this.table.name, column, argument));
              },
            })));
        continue;
      }
      result.push(m(MenuItem, {
        label: column.name,
        onclick: () => addColumn(
          columnFromSqlTableColumn(column),
        ),
      }));
    }
    return result;
  }

  renderColumnHeader(column: Column, index: number) {
    const sorted = this.state.isSortedBy(column);
    const icon = sorted === 'ASC' ?
      Icons.SortedAsc :
      sorted === 'DESC' ? Icons.SortedDesc : Icons.ContextMenu;
    return m(
      PopupMenu2,
      {
        trigger: m(Anchor, {icon}, column.title),
      },
      sorted !== 'DESC' && m(MenuItem, {
        label: 'Sort: highest first',
        icon: Icons.SortedDesc,
        onclick: () => {
          this.state.sortBy({column, direction: 'DESC'});
        },
      }),
      sorted !== 'ASC' && m(MenuItem, {
        label: 'Sort: lowest first',
        icon: Icons.SortedAsc,
        onclick: () => {
          this.state.sortBy({column, direction: 'ASC'});
        },
      }),
      sorted !== undefined && m(MenuItem, {
        label: 'Unsort',
        icon: Icons.Close,
        onclick: () => this.state.unsort(),
      }),
      this.state.getSelectedColumns().length > 1 && m(MenuItem, {
        label: 'Hide',
        icon: Icons.Hide,
        onclick: () => this.state.hideColumnAtIndex(index),
      }),
      m(MenuDivider),
      m(MenuItem,
        {label: 'Add column', icon: Icons.AddColumn},
        this.renderAddColumnOptions((column) => {
          this.state.addColumn(column, index);
        })),
    );
  }

  view() {
    const rows = this.state.getDisplayedRows();

    return [
      m('div', this.renderFilters()),
      m(BasicTable, {
        data: rows,
        columns: this.state.getSelectedColumns().map(
          (column, i) => ({
            title: this.renderColumnHeader(column, i),
            render: (row: Row) => renderCell(column, row, this.state),
          })),
      }),
      this.state.isLoading() && m(Spinner),
      this.state.getQueryError() !== undefined &&
          m('.query-error', this.state.getQueryError()),
    ];
  }
};

export {SqlTableDescription};
