// Copyright (C) 2019 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 * as m from 'mithril';
import {QueryResponse} from 'src/common/queries';

import {Actions} from '../common/actions';
import {LogExists, LogExistsKey} from '../common/logs';
import {DEFAULT_PIVOT_TABLE_ID} from '../common/pivot_table_common';

import {AggregationPanel} from './aggregation_panel';
import {ChromeSliceDetailsPanel} from './chrome_slice_panel';
import {CounterDetailsPanel} from './counter_panel';
import {CpuProfileDetailsPanel} from './cpu_profile_panel';
import {DragGestureHandler} from './drag_gesture_handler';
import {
  FlowEventsAreaSelectedPanel,
  FlowEventsPanel
} from './flow_events_panel';
import {globals} from './globals';
import {HeapProfileDetailsPanel} from './heap_profile_panel';
import {LogPanel} from './logs_panel';
import {showModal} from './modal';
import {NotesEditorPanel} from './notes_panel';
import {AnyAttrsVnode, PanelContainer} from './panel_container';
import {PivotTable} from './pivot_table';
import {ColumnDisplay, ColumnPicker} from './pivot_table_editor';
import {PivotTableHelper} from './pivot_table_helper';
import {QueryTable} from './query_table';
import {SliceDetailsPanel} from './slice_panel';
import {ThreadStatePanel} from './thread_state_panel';

const UP_ICON = 'keyboard_arrow_up';
const DOWN_ICON = 'keyboard_arrow_down';
const DRAG_HANDLE_HEIGHT_PX = 28;
const DEFAULT_DETAILS_HEIGHT_PX = 230 + DRAG_HANDLE_HEIGHT_PX;

function getFullScreenHeight() {
  const panelContainer =
      document.querySelector('.pan-and-zoom-content') as HTMLElement;
  if (panelContainer !== null) {
    return panelContainer.clientHeight;
  } else {
    return DEFAULT_DETAILS_HEIGHT_PX;
  }
}

function hasLogs(): boolean {
  const data = globals.trackDataStore.get(LogExistsKey) as LogExists;
  return data && data.exists;
}

function showPivotTableEditorModal(helper?: PivotTableHelper) {
  if (helper !== undefined && helper.editPivotTableModalOpen) {
    let content;
    if (helper.availableColumns.length === 0 ||
        helper.availableAggregations.length === 0) {
      content =
          m('.pivot-table-editor-container',
            helper.availableColumns.length === 0 ?
                m('div', 'No columns available.') :
                null,
            helper.availableAggregations.length === 0 ?
                m('div', 'No aggregations available.') :
                null);
    } else {
      const attrs = {helper};
      content =
          m('.pivot-table-editor-container',
            m(ColumnPicker, attrs),
            m(ColumnDisplay, attrs));
    }

    showModal({
      title: 'Edit Pivot Table',
      content,
      buttons: [],
    }).finally(() => {
      helper.toggleEditPivotTableModal();
      globals.rafScheduler.scheduleFullRedraw();
    });
  }
}

interface Tab {
  key: string;
  name: string;
}

interface DragHandleAttrs {
  height: number;
  resize: (height: number) => void;
  tabs: Tab[];
}

class DragHandle implements m.ClassComponent<DragHandleAttrs> {
  private dragStartHeight = 0;
  private height = 0;
  private previousHeight = this.height;
  private resize: (height: number) => void = () => {};
  private isClosed = this.height <= DRAG_HANDLE_HEIGHT_PX;
  private isFullscreen = false;
  // We can't get real fullscreen height until the pan_and_zoom_handler exists.
  private fullscreenHeight = DEFAULT_DETAILS_HEIGHT_PX;

  oncreate({dom, attrs}: m.CVnodeDOM<DragHandleAttrs>) {
    this.resize = attrs.resize;
    this.height = attrs.height;
    this.isClosed = this.height <= DRAG_HANDLE_HEIGHT_PX;
    this.fullscreenHeight = getFullScreenHeight();
    const elem = dom as HTMLElement;
    new DragGestureHandler(
        elem,
        this.onDrag.bind(this),
        this.onDragStart.bind(this),
        this.onDragEnd.bind(this));
  }

  onupdate({attrs}: m.CVnodeDOM<DragHandleAttrs>) {
    this.resize = attrs.resize;
    this.height = attrs.height;
    this.isClosed = this.height <= DRAG_HANDLE_HEIGHT_PX;
  }

  onDrag(_x: number, y: number) {
    const newHeight =
        Math.floor(this.dragStartHeight + (DRAG_HANDLE_HEIGHT_PX / 2) - y);
    this.isClosed = newHeight <= DRAG_HANDLE_HEIGHT_PX;
    this.isFullscreen = newHeight >= this.fullscreenHeight;
    this.resize(newHeight);
    globals.rafScheduler.scheduleFullRedraw();
  }

  onDragStart(_x: number, _y: number) {
    this.dragStartHeight = this.height;
  }

  onDragEnd() {}

  view({attrs}: m.CVnode<DragHandleAttrs>) {
    const icon = this.isClosed ? UP_ICON : DOWN_ICON;
    const title = this.isClosed ? 'Show panel' : 'Hide panel';
    const activeTabExists = globals.state.currentTab &&
        attrs.tabs.map(tab => tab.key).includes(globals.state.currentTab);
    if (!activeTabExists) {
      globals.dispatch(Actions.setCurrentTab({tab: undefined}));
    }
    const renderTab = (tab: Tab) => {
      if (globals.state.currentTab === tab.key ||
          globals.state.currentTab === undefined &&
              attrs.tabs[0].key === tab.key) {
        // Update currentTab in case we didn't have one before.
        globals.dispatch(Actions.setCurrentTab({tab: tab.key}));
        return m('.tab[active]', tab.name);
      }
      return m(
          '.tab',
          {
            onclick: () => {
              globals.dispatch(Actions.setCurrentTab({tab: tab.key}));
            }
          },
          tab.name);
    };
    return m(
        '.handle',
        m('.tabs', attrs.tabs.map(renderTab)),
        m('.buttons',
          m('i.material-icons',
            {
              onclick: () => {
                this.isClosed = false;
                this.isFullscreen = true;
                this.resize(this.fullscreenHeight);
                globals.rafScheduler.scheduleFullRedraw();
              },
              title: 'Open fullscreen',
              disabled: this.isFullscreen
            },
            'vertical_align_top'),
          m('i.material-icons',
            {
              onclick: () => {
                if (this.height === DRAG_HANDLE_HEIGHT_PX) {
                  this.isClosed = false;
                  if (this.previousHeight === 0) {
                    this.previousHeight = DEFAULT_DETAILS_HEIGHT_PX;
                  }
                  this.resize(this.previousHeight);
                } else {
                  this.isFullscreen = false;
                  this.isClosed = true;
                  this.previousHeight = this.height;
                  this.resize(DRAG_HANDLE_HEIGHT_PX);
                }
                globals.rafScheduler.scheduleFullRedraw();
              },
              title
            },
            icon)));
  }
}

export class DetailsPanel implements m.ClassComponent {
  private detailsHeight = DEFAULT_DETAILS_HEIGHT_PX;
  // Used to set details panel to default height on selection.
  private showDetailsPanel = true;

  view() {
    interface DetailsPanel {
      key: string;
      name: string;
      vnode: AnyAttrsVnode;
    }

    const detailsPanels: DetailsPanel[] = [];
    const curSelection = globals.state.currentSelection;
    if (curSelection) {
      switch (curSelection.kind) {
        case 'NOTE':
          detailsPanels.push({
            key: 'current_selection',
            name: 'Current Selection',
            vnode: m(NotesEditorPanel, {
              key: 'notes',
              id: curSelection.id,
            })
          });
          break;
        case 'AREA':
          if (curSelection.noteId !== undefined) {
            detailsPanels.push({
              key: 'current_selection',
              name: 'Current Selection',
              vnode: m(NotesEditorPanel, {
                key: 'area_notes',
                id: curSelection.noteId,
              })
            });
          }
          break;
        case 'SLICE':
          detailsPanels.push({
            key: 'current_selection',
            name: 'Current Selection',
            vnode: m(SliceDetailsPanel, {
              key: 'slice',
            })
          });
          break;
        case 'COUNTER':
          detailsPanels.push({
            key: 'current_selection',
            name: 'Current Selection',
            vnode: m(CounterDetailsPanel, {
              key: 'counter',
            })
          });
          break;
        case 'PERF_SAMPLES':
        case 'HEAP_PROFILE':
          detailsPanels.push({
            key: 'current_selection',
            name: 'Current Selection',
            vnode: m(HeapProfileDetailsPanel, {key: 'heap_profile'})
          });
          break;
        case 'CPU_PROFILE_SAMPLE':
          detailsPanels.push({
            key: 'current_selection',
            name: 'Current Selection',
            vnode: m(CpuProfileDetailsPanel, {
              key: 'cpu_profile_sample',
            })
          });
          break;
        case 'CHROME_SLICE':
          detailsPanels.push({
            key: 'current_selection',
            name: 'Current Selection',
            vnode: m(ChromeSliceDetailsPanel, {key: 'chrome_slice'})
          });
          break;
        case 'THREAD_STATE':
          detailsPanels.push({
            key: 'current_selection',
            name: 'Current Selection',
            vnode: m(ThreadStatePanel, {key: 'thread_state'})
          });
          break;
        default:
          break;
      }
    }
    if (hasLogs()) {
      detailsPanels.push({
        key: 'android_logs',
        name: 'Android Logs',
        vnode: m(LogPanel, {key: 'logs_panel'})
      });
    }

    if (globals.queryResults.has('command')) {
      const count =
          (globals.queryResults.get('command') as QueryResponse).rows.length;
      detailsPanels.push({
        key: 'query_result',
        name: `Query Result (${count})`,
        vnode: m(QueryTable, {key: 'query', queryId: 'command'})
      });
    }

    for (const pivotTableId of Object.keys(globals.state.pivotTable)) {
      const pivotTable = globals.state.pivotTable[pivotTableId];
      const helper = globals.pivotTableHelper.get(pivotTableId);
      if (pivotTableId !== DEFAULT_PIVOT_TABLE_ID ||
          globals.frontendLocalState.showPivotTable) {
        if (helper !== undefined) {
          helper.setSelectedPivotsAndAggregations(
              pivotTable.selectedPivots, pivotTable.selectedAggregations);
        }
        detailsPanels.push({
          key: pivotTableId,
          name: pivotTable.name,
          vnode: m(PivotTable, {key: pivotTableId, pivotTableId, helper})
        });
      }
      showPivotTableEditorModal(helper);
    }

    if (globals.connectedFlows.length > 0) {
      detailsPanels.push({
        key: 'bound_flows',
        name: 'Flow Events',
        vnode: m(FlowEventsPanel, {key: 'flow_events'})
      });
    }

    for (const [key, value] of globals.aggregateDataStore.entries()) {
      if (value.columns.length > 0 && value.columns[0].data.length > 0) {
        detailsPanels.push({
          key: value.tabName,
          name: value.tabName,
          vnode: m(AggregationPanel, {kind: key, key, data: value})
        });
      }
    }

    // Add this after all aggregation panels, to make it appear after 'Slices'
    if (globals.selectedFlows.length > 0) {
      detailsPanels.push({
        key: 'selected_flows',
        name: 'Flow Events',
        vnode: m(FlowEventsAreaSelectedPanel)
      });
    }

    this.showDetailsPanel = detailsPanels.length > 0;

    const currentTabDetails =
        detailsPanels.filter(tab => tab.key === globals.state.currentTab)[0];

    const panel = currentTabDetails ?
        currentTabDetails.vnode :
        detailsPanels.values().next().value?.vnode;
    const panels = panel ? [panel] : [];

    return m(
        '.details-content',
        {
          style: {
            height: `${this.detailsHeight}px`,
            display: this.showDetailsPanel ? null : 'none'
          }
        },
        m(DragHandle, {
          resize: (height: number) => {
            this.detailsHeight = Math.max(height, DRAG_HANDLE_HEIGHT_PX);
          },
          height: this.detailsHeight,
          tabs: detailsPanels.map(tab => {
            return {key: tab.key, name: tab.name};
          }),
        }),
        m('.details-panel-container',
          m(PanelContainer, {doesScroll: true, panels, kind: 'DETAILS'})));
  }
}
