// 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 {globals} from './globals';
import {QueryTable} from './query_table';

export function runQueryInNewTab(query: string, title: string, tag?: string) {
  return addTab({
    kind: QueryResultTab.kind,
    tag,
    config: {
      query,
      title,
    },
  });
}

globals.registerOpenQueryHandler(runQueryInNewTab);

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;
}

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

  queryResponse?: QueryResponse;
  sqlViewName?: string;

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

  constructor(args: NewBottomTabArgs) {
    super(args);

    this.initTrack(args);
  }

  async initTrack(args: NewBottomTabArgs) {
    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);
