// Copyright (C) 2018 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 {Actions} from '../common/actions';
import {QueryResponse} from '../common/queries';
import {EngineConfig} from '../common/state';

import {globals} from './globals';

const QUERY_ID = 'quicksearch';

let selResult = 0;
let numResults = 0;
let mode: 'search'|'command' = 'search';
let omniboxValue = '';

function clearOmniboxResults() {
  globals.queryResults.delete(QUERY_ID);
  globals.dispatch(Actions.deleteQuery({queryId: QUERY_ID}));
}

function onKeyDown(e: Event) {
  e.stopPropagation();
  const key = (e as KeyboardEvent).key;

  // Avoid that the global 'a', 'd', 'w', 's' handler sees these keystrokes.
  // TODO: this seems a bug in the pan_and_zoom_handler.ts.
  if (key === 'ArrowUp' || key === 'ArrowDown') {
    e.preventDefault();
    return;
  }
  const txt = (e.target as HTMLInputElement);
  omniboxValue = txt.value;
  if (key === ':' && txt.value === '') {
    mode = 'command';
    globals.rafScheduler.scheduleFullRedraw();
    e.preventDefault();
    return;
  }
  if (key === 'Escape' && mode === 'command') {
    txt.value = '';
    mode = 'search';
    globals.rafScheduler.scheduleFullRedraw();
    return;
  }
  if (key === 'Backspace' && txt.value.length === 0 && mode === 'command') {
    mode = 'search';
    globals.rafScheduler.scheduleFullRedraw();
    return;
  }
}

function onKeyUp(e: Event) {
  e.stopPropagation();
  const key = (e as KeyboardEvent).key;
  const txt = e.target as HTMLInputElement;
  omniboxValue = txt.value;
  if (key === 'ArrowUp' || key === 'ArrowDown') {
    selResult += (key === 'ArrowUp') ? -1 : 1;
    selResult = Math.max(selResult, 0);
    selResult = Math.min(selResult, numResults - 1);
    e.preventDefault();
    globals.rafScheduler.scheduleFullRedraw();
    return;
  }
  if (txt.value.length <= 0 || key === 'Escape') {
    clearOmniboxResults();
    globals.rafScheduler.scheduleFullRedraw();
    return;
  }
  if (mode === 'search') {
    const name = txt.value.replace(/'/g, '\\\'').replace(/[*]/g, '%');
    const query = `select str from strings where str like '%${name}%' limit 10`;
    globals.dispatch(
        Actions.executeQuery({engineId: '0', queryId: QUERY_ID, query}));
  }
  if (mode === 'command' && key === 'Enter') {
    globals.dispatch(Actions.executeQuery(
        {engineId: '0', queryId: 'command', query: txt.value}));
  }
}


class Omnibox implements m.ClassComponent {
  oncreate(vnode: m.VnodeDOM) {
    const txt = vnode.dom.querySelector('input') as HTMLInputElement;
    txt.addEventListener('blur', clearOmniboxResults);
    txt.addEventListener('keydown', onKeyDown);
    txt.addEventListener('keyup', onKeyUp);
  }

  view() {
    const msgTTL = globals.state.status.timestamp + 1 - Date.now() / 1e3;
    let enginesAreBusy = false;
    for (const engine of Object.values(globals.state.engines)) {
      enginesAreBusy = enginesAreBusy || !engine.ready;
    }

    if (msgTTL > 0 || enginesAreBusy) {
      setTimeout(
          () => globals.rafScheduler.scheduleFullRedraw(), msgTTL * 1000);
      return m(
          `.omnibox.message-mode`,
          m(`input[placeholder=${globals.state.status.msg}][readonly]`, {
            value: '',
          }));
    }

    // TODO(primiano): handle query results here.
    const results = [];
    const resp = globals.queryResults.get(QUERY_ID) as QueryResponse;
    if (resp !== undefined) {
      numResults = resp.rows ? resp.rows.length : 0;
      for (let i = 0; i < resp.rows.length; i++) {
        const clazz = (i === selResult) ? '.selected' : '';
        results.push(m(`div${clazz}`, resp.rows[i][resp.columns[0]]));
      }
    }
    const placeholder = {
      search: 'Search or type : to enter command mode',
      command: 'e.g., select * from sched left join thread using(utid) limit 10'
    };

    const commandMode = mode === 'command';
    return m(
        `.omnibox${commandMode ? '.command-mode' : ''}`,
        m(`input[placeholder=${placeholder[mode]}]`, {
          onchange: m.withAttr('value', v => omniboxValue = v),
          value: omniboxValue,
        }),
        m('.omnibox-results', results));
  }
}

export class Topbar implements m.ClassComponent {
  view() {
    const progBar = [];
    const engine: EngineConfig = globals.state.engines['0'];
    if (globals.state.queries[QUERY_ID] !== undefined ||
        (engine !== undefined && !engine.ready)) {
      progBar.push(m('.progress'));
    }
    return m('.topbar', m(Omnibox), ...progBar);
  }
}
