// Copyright (C) 2022 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 m from 'mithril';

import {Actions} from '../common/actions';
import {globals} from './globals';

export const LOG_PRIORITIES =
    ['-', '-', 'Verbose', 'Debug', 'Info', 'Warn', 'Error', 'Fatal'];
const IGNORED_STATES = 2;

interface LogPriorityWidgetAttrs {
  options: string[];
  selectedIndex: number;
  onSelect: (id: number) => void;
}

interface LogTagChipAttrs {
  name: string;
  removeTag: (name: string) => void;
}

interface LogTagsWidgetAttrs {
  tags: string[];
}

interface FilterByTextWidgetAttrs {
  hideNonMatching: boolean;
}

class LogPriorityWidget implements m.ClassComponent<LogPriorityWidgetAttrs> {
  view(vnode: m.Vnode<LogPriorityWidgetAttrs>) {
    const attrs = vnode.attrs;
    const optionComponents = [];
    for (let i = IGNORED_STATES; i < attrs.options.length; i++) {
      const selected = i === attrs.selectedIndex;
      optionComponents.push(
          m('option', {value: i, selected}, attrs.options[i]));
    }
    return m(
        'select',
        {
          onchange: (e: InputEvent) => {
            const selectionValue = (e.target as HTMLSelectElement).value;
            attrs.onSelect(Number(selectionValue));
          },
        },
        optionComponents,
    );
  }
}

class LogTagChip implements m.ClassComponent<LogTagChipAttrs> {
  view({attrs}: m.CVnode<LogTagChipAttrs>) {
    return m(
        '.chip',
        m('.chip-text', attrs.name),
        m('button.chip-button',
          {
            onclick: () => {
              attrs.removeTag(attrs.name);
            },
          },
          '×'));
  }
}

class LogTagsWidget implements m.ClassComponent<LogTagsWidgetAttrs> {
  removeTag(tag: string) {
    globals.dispatch(Actions.removeLogTag({tag}));
  }

  view(vnode: m.Vnode<LogTagsWidgetAttrs>) {
    const tags = vnode.attrs.tags;
    return m(
        '.tag-container',
        m('.chips', tags.map((tag) => m(LogTagChip, {
                               name: tag,
                               removeTag: this.removeTag.bind(this),
                             }))),
        m(`input.chip-input[placeholder='Add new tag']`, {
          onkeydown: (e: KeyboardEvent) => {
            // This is to avoid zooming on 'w'(and other unexpected effects
            // of key presses in this input field).
            e.stopPropagation();
            const htmlElement = e.target as HTMLInputElement;

            // When the user clicks 'Backspace' we delete the previous tag.
            if (e.key === 'Backspace' && tags.length > 0 &&
                htmlElement.value === '') {
              globals.dispatch(
                  Actions.removeLogTag({tag: tags[tags.length - 1]}));
              return;
            }

            if (e.key !== 'Enter') {
              return;
            }
            if (htmlElement.value === '') {
              return;
            }
            globals.dispatch(
                Actions.addLogTag({tag: htmlElement.value.trim()}));
            htmlElement.value = '';
          },
        }));
  }
}

class LogTextWidget implements m.ClassComponent {
  view() {
    return m(
        '.tag-container', m(`input.chip-input[placeholder='Search log text']`, {
          onkeydown: (e: KeyboardEvent) => {
            // This is to avoid zooming on 'w'(and other unexpected effects
            // of key presses in this input field).
            e.stopPropagation();
          },

          onkeyup: (e: KeyboardEvent) => {
            // We want to use the value of the input field after it has been
            // updated with the latest key (onkeyup).
            const htmlElement = e.target as HTMLInputElement;
            globals.dispatch(
                Actions.updateLogFilterText({textEntry: htmlElement.value}));
          },
        }));
  }
}

class FilterByTextWidget implements m.ClassComponent<FilterByTextWidgetAttrs> {
  view({attrs}: m.Vnode<FilterByTextWidgetAttrs>) {
    const icon = attrs.hideNonMatching ? 'unfold_less' : 'unfold_more';
    const tooltip = attrs.hideNonMatching ? 'Expand all and view highlighted' :
                                            'Collapse all';
    return m(
        '.filter-widget',
        m('.tooltip', tooltip),
        m('i.material-icons',
          {
            onclick: () => {
              globals.dispatch(Actions.toggleCollapseByTextEntry({}));
            },
          },
          icon));
  }
}

export class LogsFilters implements m.ClassComponent {
  view(_: m.CVnode<{}>) {
    return m(
        '.log-filters',
        m('.log-label', 'Log Level'),
        m(LogPriorityWidget, {
          options: LOG_PRIORITIES,
          selectedIndex: globals.state.logFilteringCriteria.minimumLevel,
          onSelect: (minimumLevel) => {
            globals.dispatch(Actions.setMinimumLogLevel({minimumLevel}));
          },
        }),
        m(LogTagsWidget, {tags: globals.state.logFilteringCriteria.tags}),
        m(LogTextWidget),
        m(FilterByTextWidget, {
          hideNonMatching: globals.state.logFilteringCriteria.hideNonMatching,
        }));
  }
}
