// 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 {v4 as uuidv4} from 'uuid';

import {assertExists} from '../base/logging';
import {QueryResponse, runQuery} from '../common/queries';
import {raf} from '../core/raf_scheduler';
import {QueryError} from '../trace_processor/query_result';
import {
  AddDebugTrackMenu,
  uuidToViewName,
} from '../tracks/debug/add_debug_track_menu';
import {Button} from '../widgets/button';
import {PopupMenu2} from '../widgets/menu';
import {PopupPosition} from '../widgets/popup';

import {
  addTab,
  BottomTab,
  bottomTabRegistry,
  closeTab,
  NewBottomTabArgs,
} from './bottom_tab';
import {QueryTable} from './query_table';
import {TABS_V2_FLAG} from '../core/feature_flags';
import {globals} from './globals';
import {Actions} from '../common/actions';
import {BottomTabToTabAdapter} from '../public/utils';
import {EngineProxy} from '../public';

interface QueryResultTabConfig {
  readonly query: string;
  readonly title: string;
  // Optional data to display in this tab instead of fetching it again
  // (e.g. when duplicating an existing tab which already has the data).
  readonly prefetchedResponse?: QueryResponse;
}

// External interface for adding a new query results tab
// Automatically decided whether to add v1 or v2 tab
export function addQueryResultsTab(
  config: QueryResultTabConfig, tag?: string): void {
  if (TABS_V2_FLAG.get()) {
    const queryResultsTab = new QueryResultTab({
      config,
      engine: getEngine(),
      uuid: uuidv4(),
    });

    const uri = 'queryResults#' + (tag ?? uuidv4());

    globals.tabManager.registerTab({
      uri,
      content: new BottomTabToTabAdapter(queryResultsTab),
      isEphemeral: true,
    });

    globals.dispatch(Actions.showTab({uri}));
  } else {
    return addTab({
      kind: QueryResultTab.kind,
      tag,
      config,
    });
  }
}

// TODO(stevegolton): Find a way to make this more elegant.
function getEngine(): EngineProxy {
  const engConfig = globals.getCurrentEngine();
  const engineId = assertExists(engConfig).id;
  return assertExists(globals.engines.get(engineId)).getProxy('QueryResult');
}

export class QueryResultTab extends BottomTab<QueryResultTabConfig> {
  static readonly kind = 'dev.perfetto.QueryResultTab';

  queryResponse?: QueryResponse;
  sqlViewName?: string;

  static create(args: NewBottomTabArgs<QueryResultTabConfig>): QueryResultTab {
    return new QueryResultTab(args);
  }

  constructor(args: NewBottomTabArgs<QueryResultTabConfig>) {
    super(args);

    this.initTrack(args);
  }

  async initTrack(args: NewBottomTabArgs<QueryResultTabConfig>) {
    let uuid = '';
    if (this.config.prefetchedResponse !== undefined) {
      this.queryResponse = this.config.prefetchedResponse;
      uuid = args.uuid;
    } else {
      const result = await runQuery(this.config.query, this.engine);
      this.queryResponse = result;
      raf.scheduleFullRedraw();
      if (result.error !== undefined) {
        return;
      }

      uuid = uuidv4();
    }

    if (uuid !== '') {
      this.sqlViewName = await this.createViewForDebugTrack(uuid);
      if (this.sqlViewName) {
        raf.scheduleFullRedraw();
      }
    }
  }

  getTitle(): string {
    const suffix =
        this.queryResponse ? ` (${this.queryResponse.rows.length})` : '';
    return `${this.config.title}${suffix}`;
  }

  viewTab(): m.Child {
    return m(QueryTable, {
      query: this.config.query,
      resp: this.queryResponse,
      fillParent: true,
      onClose: () => closeTab(this.uuid),
      contextButtons: [
        this.sqlViewName === undefined ?
          null :
          m(PopupMenu2,
            {
              trigger: m(Button, {label: 'Show debug track', minimal: true}),
              popupPosition: PopupPosition.Top,
            },
            m(AddDebugTrackMenu, {
              dataSource: {
                sqlSource: `select * from ${this.sqlViewName}`,
                columns: assertExists(this.queryResponse).columns,
              },
              engine: this.engine,
            })),
      ],
    });
  }

  isLoading() {
    return this.queryResponse === undefined;
  }

  async createViewForDebugTrack(uuid: string): Promise<string> {
    const viewId = uuidToViewName(uuid);
    // Assuming that the query results come from a SELECT query, try creating a
    // view to allow us to reuse it for further queries.
    const hasValidQueryResponse =
        this.queryResponse && this.queryResponse.error === undefined;
    const sqlQuery = hasValidQueryResponse ?
        this.queryResponse!.lastStatementSql :
      this.config.query;
    try {
      const createViewResult =
          await this.engine.query(`create view ${viewId} as ${sqlQuery}`);
      if (createViewResult.error()) {
        // If it failed, do nothing.
        return '';
      }
    } catch (e) {
      if (e instanceof QueryError) {
        // If it failed, do nothing.
        return '';
      }
      throw e;
    }
    return viewId;
  }
}

bottomTabRegistry.register(QueryResultTab);
