// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use size 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 {Actions} from '../common/actions';
import {
  AggregateData,
  Column,
  ThreadStateExtra
} from '../common/aggregation_data';
import {colorForState, textColorForState} from '../common/colorizer';
import {translateState} from '../common/thread_state';

import {globals} from './globals';
import {Panel} from './panel';

export interface AggregationPanelAttrs {
  data: AggregateData;
  kind: string;
}

export class AggregationPanel extends Panel<AggregationPanelAttrs> {
  view({attrs}: m.CVnode<AggregationPanelAttrs>) {
    return m(
        '.details-panel',
        m('.details-panel-heading.aggregation',
          attrs.data.extra !== undefined &&
                  attrs.data.extra.kind === 'THREAD_STATE' ?
              this.showStateSummary(attrs.data.extra) :
              null,
          this.showTimeRange(),
          m('table',
            m('tr',
              attrs.data.columns.map(
                  col => this.formatColumnHeading(col, attrs.kind))))),
        m(
            '.details-table.aggregation',
            m('table', this.getRows(attrs.data)),
            ));
  }

  formatColumnHeading(col: Column, id: string) {
    const pref = globals.state.aggregatePreferences[id];
    let sortIcon = '';
    if (pref && pref.sorting && pref.sorting.column === col.columnId) {
      sortIcon = pref.sorting.direction === 'DESC' ? 'arrow_drop_down' :
                                                     'arrow_drop_up';
    }
    return m(
        'th',
        {
          onclick: () => {
            globals.dispatch(
                Actions.updateAggregateSorting({id, column: col.columnId}));
          }
        },
        col.title,
        m('i.material-icons', sortIcon));
  }

  getRows(data: AggregateData) {
    if (data.columns.length === 0) return;
    const rows = [];
    for (let i = 0; i < data.columns[0].data.length; i++) {
      const row = [];
      for (let j = 0; j < data.columns.length; j++) {
        row.push(m('td', this.getFormattedData(data, i, j)));
      }
      rows.push(m('tr', row));
    }
    return rows;
  }

  getFormattedData(data: AggregateData, rowIndex: number, columnIndex: number) {
    switch (data.columns[columnIndex].kind) {
      case 'STRING':
        return data.strings[data.columns[columnIndex].data[rowIndex]];
      case 'TIMESTAMP_NS':
        return `${data.columns[columnIndex].data[rowIndex] / 1000000}`;
      case 'STATE': {
        const concatState =
            data.strings[data.columns[columnIndex].data[rowIndex]];
        const split = concatState.split(',');
        const ioWait =
            split[1] === 'NULL' ? undefined : !!Number.parseInt(split[1], 10);
        return translateState(split[0], ioWait);
      }
      case 'NUMBER':
      default:
        return data.columns[columnIndex].data[rowIndex];
    }
  }

  showTimeRange() {
    const selection = globals.state.currentSelection;
    if (selection === null || selection.kind !== 'AREA') return undefined;
    const selectedArea = globals.state.areas[selection.areaId];
    const rangeDurationMs = (selectedArea.endSec - selectedArea.startSec) * 1e3;
    return m('.time-range', `Selected range: ${rangeDurationMs.toFixed(6)} ms`);
  }

  // Thread state aggregation panel only
  showStateSummary(data: ThreadStateExtra) {
    if (data === undefined) return undefined;
    const states = [];
    for (let i = 0; i < data.states.length; i++) {
      const color = colorForState(data.states[i]);
      const textColor = textColorForState(data.states[i]);
      const width = data.values[i] / data.totalMs * 100;
      states.push(
          m('.state',
            {
              style: {
                background: `hsl(${color.h},${color.s}%,${color.l}%)`,
                color: `${textColor}`,
                width: `${width}%`
              }
            },
            `${data.states[i]}: ${data.values[i]} ms`));
    }
    return m('.states', states);
  }

  renderCanvas() {}
}