// 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 {Actions} from '../common/actions';
import {Area} from '../common/state';

import {Flow, globals} from './globals';
import {toggleHelp} from './help_modal';
import {
  findUiTrackId,
  horizontalScrollAndZoomToRange,
  verticalScrollToTrack
} from './scroll_helper';
import {executeSearch} from './search_handler';

type Direction = 'Forward'|'Backward';

// Handles all key events than are not handled by the
// pan and zoom handler.
export function handleKey(e: KeyboardEvent, down: boolean) {
  const key = e.key.toLowerCase();
  const selection = globals.state.currentSelection;
  if (down && 'm' === key) {
    if (selection && selection.kind === 'AREA') {
      globals.dispatch(Actions.toggleMarkCurrentArea({persistent: e.shiftKey}));
    } else if (selection) {
      lockSliceSpan(e.shiftKey);
    }
  }
  if (down && 'f' === key) {
    findCurrentSelection();
  }
  if (down && 'v' === key) {
    globals.dispatch(Actions.toggleVideo({}));
  }
  if (down && 'p' === key) {
    globals.dispatch(Actions.toggleFlagPause({}));
  }
  if (down && 't' === key) {
    globals.dispatch(Actions.toggleScrubbing({}));
    if (globals.frontendLocalState.vidTimestamp < 0) {
      globals.frontendLocalState.setVidTimestamp(Number.MAX_SAFE_INTEGER);
    } else {
      globals.frontendLocalState.setVidTimestamp(Number.MIN_SAFE_INTEGER);
    }
  }
  if (down && 'b' === key && (e.ctrlKey || e.metaKey)) {
    globals.frontendLocalState.toggleSidebar();
  }
  if (down && '?' === key) {
    toggleHelp();
  }
  if (down && 'enter' === key) {
    e.preventDefault();
    executeSearch(e.shiftKey);
  }
  if (down && 'escape' === key) {
    globals.frontendLocalState.deselectArea();
    globals.makeSelection(Actions.deselect({}));
    globals.dispatch(Actions.removeNote({id: '0'}));
  }
  if (down && ']' === key) {
    if (e.ctrlKey) {
      focusOtherFlow('Forward');
    } else {
      moveByFocusedFlow('Forward');
    }
  }
  if (down && '[' === key) {
    if (e.ctrlKey) {
      focusOtherFlow('Backward');
    } else {
      moveByFocusedFlow('Backward');
    }
  }
}

// Search |boundFlows| for |flowId| and return the id following it.
// Returns the first flow id if nothing was found or |flowId| was the last flow
// in |boundFlows|, and -1 if |boundFlows| is empty
function findAnotherFlowExcept(boundFlows: Flow[], flowId: number): number {
  let selectedFlowFound = false;

  if (boundFlows.length === 0) {
    return -1;
  }

  for (const flow of boundFlows) {
    if (selectedFlowFound) {
      return flow.id;
    }

    if (flow.id === flowId) {
      selectedFlowFound = true;
    }
  }
  return boundFlows[0].id;
}

// Change focus to the next flow event (matching the direction)
function focusOtherFlow(direction: Direction) {
  if (!globals.state.currentSelection ||
      globals.state.currentSelection.kind !== 'CHROME_SLICE') {
    return;
  }
  const sliceId = globals.state.currentSelection.id;
  if (sliceId === -1) {
    return;
  }

  const boundFlows = globals.connectedFlows.filter(
      flow => flow.begin.sliceId === sliceId && direction === 'Forward' ||
          flow.end.sliceId === sliceId && direction === 'Backward');

  if (direction === 'Backward') {
    const nextFlowId = findAnotherFlowExcept(
        boundFlows, globals.frontendLocalState.focusedFlowIdLeft);
    globals.frontendLocalState.setHighlightedFlowLeftId(nextFlowId);
  } else {
    const nextFlowId = findAnotherFlowExcept(
        boundFlows, globals.frontendLocalState.focusedFlowIdRight);
    globals.frontendLocalState.setHighlightedFlowRightId(nextFlowId);
  }
}

// Select the slice connected to the flow in focus
function moveByFocusedFlow(direction: Direction) {
  if (!globals.state.currentSelection ||
      globals.state.currentSelection.kind !== 'CHROME_SLICE') {
    return;
  }

  const sliceId = globals.state.currentSelection.id;
  const flowId =
      (direction === 'Backward' ?
           globals.frontendLocalState.focusedFlowIdLeft :
           globals.frontendLocalState.focusedFlowIdRight);

  if (sliceId === -1 || flowId === -1) {
    return;
  }

  // Find flow that is in focus and select corresponding slice
  for (const flow of globals.connectedFlows) {
    if (flow.id === flowId) {
      const flowPoint = (direction === 'Backward' ? flow.begin : flow.end);
      const uiTrackId = findUiTrackId(flowPoint.trackId);
      if (uiTrackId) {
        globals.makeSelection(Actions.selectChromeSlice(
            {id: flowPoint.sliceId, trackId: uiTrackId, table: 'slice'}));
      }
    }
  }
}

function findTimeRangeOfSelection() {
  const selection = globals.state.currentSelection;
  let startTs = -1;
  let endTs = -1;
  if (selection !== null) {
    if (selection.kind === 'SLICE' || selection.kind === 'CHROME_SLICE') {
      const slice = globals.sliceDetails;
      if (slice.ts && slice.dur) {
        startTs = slice.ts + globals.state.traceTime.startSec;
        endTs = startTs + slice.dur;
      }
    } else if (selection.kind === 'THREAD_STATE') {
      const threadState = globals.threadStateDetails;
      if (threadState.ts && threadState.dur) {
        startTs = threadState.ts + globals.state.traceTime.startSec;
        endTs = startTs + threadState.dur;
      }
    } else if (selection.kind === 'COUNTER') {
      startTs = selection.leftTs;
      endTs = selection.rightTs;
    }
  }
  return {startTs, endTs};
}


function lockSliceSpan(persistent = false) {
  const range = findTimeRangeOfSelection();
  if (range.startTs !== -1 && range.endTs !== -1 &&
      globals.state.currentSelection !== null) {
    const tracks = globals.state.currentSelection.trackId ?
        [globals.state.currentSelection.trackId] :
        [];
    const area: Area = {startSec: range.startTs, endSec: range.endTs, tracks};
    globals.dispatch(Actions.markArea({area, persistent}));
  }
}

function findCurrentSelection() {
  const selection = globals.state.currentSelection;
  if (selection === null) return;

  const range = findTimeRangeOfSelection();
  if (range.startTs !== -1 && range.endTs !== -1) {
    horizontalScrollAndZoomToRange(range.startTs, range.endTs);
  }

  if (selection.trackId) {
    verticalScrollToTrack(selection.trackId, true);
  }
}
