// 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 {drawDoubleHeadedArrow} from '../common/canvas_utils';
import {translateState} from '../common/thread_state';
import {timeToCode, toNs} from '../common/time';

import {globals, SliceDetails, ThreadDesc} from './globals';
import {PanelSize} from './panel';
import {scrollToTrackAndTs} from './scroll_helper';
import {SlicePanel} from './slice_panel';

export class SliceDetailsPanel extends SlicePanel {
  view() {
    const sliceInfo = globals.sliceDetails;
    if (sliceInfo.utid === undefined) return;
    const threadInfo = globals.threads.get(sliceInfo.utid);

    return m(
        '.details-panel',
        m('.details-panel-heading',
          m('h2.split', `Slice Details`),
          (sliceInfo.wakeupTs && sliceInfo.wakerUtid) ?
              m('h2.split', 'Scheduling Latency') :
              ''),
        this.getDetails(sliceInfo, threadInfo));
  }

  getDetails(sliceInfo: SliceDetails, threadInfo: ThreadDesc|undefined) {
    if (!threadInfo || sliceInfo.ts === undefined ||
        sliceInfo.dur === undefined) {
      return null;
    } else {
      const tableRows = [
        m('tr',
          m('th', `Process`),
          m('td', `${threadInfo.procName} [${threadInfo.pid}]`)),
        m('tr',
          m('th', `Thread`),
          m('td',
            `${threadInfo.threadName} [${threadInfo.tid}]`,
            m('i.material-icons.grey',
              {onclick: () => this.goToThread(), title: 'Go to thread'},
              'call_made'))),
        m('tr', m('th', `Cmdline`), m('td', threadInfo.cmdline)),
        m('tr', m('th', `Start time`), m('td', `${timeToCode(sliceInfo.ts)}`)),
        m('tr',
          m('th', `Duration`),
          m('td', this.computeDuration(sliceInfo.ts, sliceInfo.dur))),
        (sliceInfo.threadDur === undefined ||
         sliceInfo.threadTs === undefined) ?
            '' :
            m('tr',
              m('th', 'Thread duration'),
              m('td',
                this.computeDuration(sliceInfo.threadTs, sliceInfo.threadDur))),
        m('tr', m('th', `Prio`), m('td', `${sliceInfo.priority}`)),
        m('tr',
          m('th', `End State`),
          m('td', translateState(sliceInfo.endState))),
        m('tr',
          m('th', `Slice ID`),
          m('td', sliceInfo.id ? sliceInfo.id.toString() : 'Unknown')),
      ];

      for (const [key, value] of this.getProcessThreadDetails(sliceInfo)) {
        if (value !== undefined) {
          tableRows.push(m('tr', m('th', key), m('td', value)));
        }
      }

      return m(
          '.details-table',
          m('table.half-width', tableRows),
      );
    }
  }

  goToThread() {
    const sliceInfo = globals.sliceDetails;
    if (sliceInfo.utid === undefined) return;
    const threadInfo = globals.threads.get(sliceInfo.utid);

    if (sliceInfo.id === undefined || sliceInfo.ts === undefined ||
        sliceInfo.dur === undefined || sliceInfo.cpu === undefined ||
        threadInfo === undefined) {
      return;
    }

    let trackId: string|number|undefined;
    for (const track of Object.values(globals.state.tracks)) {
      if (track.kind === 'ThreadStateTrack' &&
          (track.config as {utid: number}).utid === threadInfo.utid) {
        trackId = track.id;
      }
    }

    if (trackId && sliceInfo.threadStateId) {
      globals.makeSelection(Actions.selectThreadState({
        id: sliceInfo.threadStateId,
        trackId: trackId.toString(),
      }));

      scrollToTrackAndTs(
          trackId, toNs(sliceInfo.ts + globals.state.traceTime.startSec), true);
    }
  }


  renderCanvas(ctx: CanvasRenderingContext2D, size: PanelSize) {
    const details = globals.sliceDetails;
    // Show expanded details on the scheduling of the currently selected slice.
    if (details.wakeupTs && details.wakerUtid !== undefined) {
      const threadInfo = globals.threads.get(details.wakerUtid);
      // Draw diamond and vertical line.
      const startDraw = {x: size.width / 2 + 20, y: 52};
      ctx.beginPath();
      ctx.moveTo(startDraw.x, startDraw.y + 28);
      ctx.fillStyle = 'black';
      ctx.lineTo(startDraw.x + 6, startDraw.y + 20);
      ctx.lineTo(startDraw.x, startDraw.y + 12);
      ctx.lineTo(startDraw.x - 6, startDraw.y + 20);
      ctx.fill();
      ctx.closePath();
      ctx.fillRect(startDraw.x - 1, startDraw.y, 2, 100);

      // Wakeup explanation text.
      ctx.font = '13px Roboto Condensed';
      ctx.fillStyle = '#3c4b5d';
      if (threadInfo) {
        const displayText = `Wakeup @ ${
            timeToCode(
                details.wakeupTs - globals.state.traceTime.startSec)} on CPU ${
            details.wakerCpu} by`;
        const processText = `P: ${threadInfo.procName} [${threadInfo.pid}]`;
        const threadText = `T: ${threadInfo.threadName} [${threadInfo.tid}]`;
        ctx.fillText(displayText, startDraw.x + 20, startDraw.y + 20);
        ctx.fillText(processText, startDraw.x + 20, startDraw.y + 37);
        ctx.fillText(threadText, startDraw.x + 20, startDraw.y + 55);
      }

      // Draw latency arrow and explanation text.
      drawDoubleHeadedArrow(ctx, startDraw.x, startDraw.y + 80, 60, true);
      if (details.ts) {
        const displayLatency = `Scheduling latency: ${
            timeToCode(
                details.ts -
                (details.wakeupTs - globals.state.traceTime.startSec))}`;
        ctx.fillText(displayLatency, startDraw.x + 70, startDraw.y + 86);
        const explain1 =
            'This is the interval from when the task became eligible to run';
        const explain2 =
            '(e.g. because of notifying a wait queue it was suspended on) to';
        const explain3 = 'when it started running.';
        ctx.font = '10px Roboto Condensed';
        ctx.fillText(explain1, startDraw.x + 70, startDraw.y + 86 + 16);
        ctx.fillText(explain2, startDraw.x + 70, startDraw.y + 86 + 16 + 12);
        ctx.fillText(explain3, startDraw.x + 70, startDraw.y + 86 + 16 + 24);
      }
    }
  }
}
