// 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 {searchSegment} from '../base/binary_search';
import {Actions} from '../common/actions';
import {toNs} from '../common/time';

import {globals} from './globals';
import {scrollToTrackAndTs} from './scroll_helper';

function setToPrevious(current: number) {
  globals.frontendLocalState.setSearchIndex(Math.max(current - 1, 0));
}

function setToNext(current: number) {
  globals.frontendLocalState.setSearchIndex(
      Math.min(current + 1, globals.currentSearchResults.totalResults - 1));
}

export function executeSearch(reverse = false) {
  const state = globals.frontendLocalState;
  const index = state.searchIndex;
  const startNs = toNs(globals.frontendLocalState.visibleWindowTime.start);
  const endNs = toNs(globals.frontendLocalState.visibleWindowTime.end);
  const currentTs = globals.currentSearchResults.tsStarts[index];

  // If this is a new search or the currentTs is not in the viewport,
  // select the first/last item in the viewport.
  if (index === -1 || currentTs < startNs || currentTs > endNs) {
    if (reverse) {
      const [smaller,] =
        searchSegment(globals.currentSearchResults.tsStarts, endNs);
      // If there is no item in the viewport just go to the previous.
      smaller === -1 ? setToPrevious(index) :
                       globals.frontendLocalState.setSearchIndex(smaller);
    } else {
      const [, larger] =
          searchSegment(globals.currentSearchResults.tsStarts, startNs);
      // If there is no item in the viewport just go to the next.
      larger === -1 ? setToNext(index) :
                      globals.frontendLocalState.setSearchIndex(larger);
    }
  } else {
    // If the currentTs is in the viewport, increment the index.
    if (reverse) {
      setToPrevious(index);
    } else {
      setToNext(index);
    }
  }
  selectCurrentSearchResult();

  // TODO(hjd): If the user does a search before any other selection,
  // the details panel will pop up when the search is executed. If the search
  // result is behind where the details panel appears then it won't get scrolled
  // to. This time delay is a workaround for this specific situation.
  // A better solution will be a callback that allows something to happen on the
  // first redraw after an Action is applied.
  const delay = index === -1 ? 50 : 0;
  setTimeout(() => moveViewportToCurrentSearch(), delay);
}

function moveViewportToCurrentSearch() {
  const searchIndex = globals.frontendLocalState.searchIndex;
  if (searchIndex === -1) return;
  const currentTs = globals.currentSearchResults.tsStarts[searchIndex];
  const trackId = globals.currentSearchResults.trackIds[searchIndex];
  scrollToTrackAndTs(trackId, currentTs);
}

function selectCurrentSearchResult() {
  const state = globals.frontendLocalState;
  const searchIndex = state.searchIndex;
  const source = globals.currentSearchResults.sources[searchIndex];
  const currentId = globals.currentSearchResults.sliceIds[searchIndex];
  const trackId = globals.currentSearchResults.trackIds[searchIndex];

  if (currentId === undefined) return;

  if (source === 'cpu') {
    globals.dispatch(Actions.selectSlice({id: currentId, trackId}));
  } else {
    // Search results only include slices from the slice table for now.
    // When we include annotations we need to pass the correct table.
    globals.dispatch(
        Actions.selectChromeSlice({id: currentId, trackId, table: 'slice'}));
  }
}
