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

import {Tree, TreeNode} from '../widgets/tree';

import {PopupMenuButton, PopupMenuItem} from './popup_menu';

// This file implements a component for rendering JSON-like values (with
// customisation options like context menu and action buttons).
//
// It defines the common Value, StringValue, DictValue, ArrayValue types,
// to be used as an interchangeable format between different components
// and `renderValue` function to convert DictValue into vdom nodes.

// Leaf (non-dict and non-array) value which can be displayed to the user
// together with the rendering customisation parameters.
type StringValue = {
  kind: 'STRING';
  value: string;
} & StringValueParams;

// Helper function to create a StringValue from string together with optional
// parameters.
export function value(value: string, params?: StringValueParams): StringValue {
  return {
    kind: 'STRING',
    value,
    ...params,
  };
}

// Helper function to convert a potentially undefined value to StringValue or
// null.
export function maybeValue(
  v?: string,
  params?: StringValueParams,
): StringValue | null {
  if (!v) {
    return null;
  }
  return value(v, params);
}

// A basic type for the JSON-like value, comprising a primitive type (string)
// and composite types (arrays and dicts).
export type Value = StringValue | Array | Dict;

// Dictionary type.
export type Dict = {
  kind: 'DICT';
  items: {[name: string]: Value};
} & ValueParams;

// Helper function to simplify creation of a dictionary.
// This function accepts and filters out nulls as values in the passed
// dictionary (useful for simplifying the code to render optional values).
export function dict(
  items: {[name: string]: Value | null},
  params?: ValueParams,
): Dict {
  const result: {[name: string]: Value} = {};
  for (const [name, value] of Object.entries(items)) {
    if (value !== null) {
      result[name] = value;
    }
  }
  return {
    kind: 'DICT',
    items: result,
    ...params,
  };
}

// Array type.
export type Array = {
  kind: 'ARRAY';
  items: Value[];
} & ValueParams;

// Helper function to simplify creation of an array.
// This function accepts and filters out nulls in the passed array (useful for
// simplifying the code to render optional values).
export function array(items: (Value | null)[], params?: ValueParams): Array {
  return {
    kind: 'ARRAY',
    items: items.filter((item: Value | null) => item !== null) as Value[],
    ...params,
  };
}

// Parameters for displaying a button next to a value to perform
// the context-dependent action (i.e. go to the corresponding slice).
type ButtonParams = {
  action: () => void;
  hoverText?: string;
  icon?: string;
};

// Customisation parameters which apply to any Value (e.g. context menu).
interface ValueParams {
  contextMenu?: PopupMenuItem[];
}

// Customisation parameters which apply for a primitive value (e.g. showing
// button next to a string, or making it clickable, or adding onhover effect).
interface StringValueParams extends ValueParams {
  leftButton?: ButtonParams;
  rightButton?: ButtonParams;
}

export function isArray(value: Value): value is Array {
  return value.kind === 'ARRAY';
}

export function isDict(value: Value): value is Dict {
  return value.kind === 'DICT';
}

export function isStringValue(value: Value): value is StringValue {
  return !isArray(value) && !isDict(value);
}

// Recursively render the given value and its children, returning a list of
// vnodes corresponding to the nodes of the table.
function renderValue(name: string, value: Value): m.Children {
  const left = [
    name,
    value.contextMenu
      ? m(PopupMenuButton, {
          icon: 'arrow_drop_down',
          items: value.contextMenu,
        })
      : null,
  ];
  if (isArray(value)) {
    const nodes = value.items.map((value: Value, index: number) => {
      return renderValue(`[${index}]`, value);
    });
    return m(TreeNode, {left, right: `array[${nodes.length}]`}, nodes);
  } else if (isDict(value)) {
    const nodes: m.Children[] = [];
    for (const key of Object.keys(value.items)) {
      nodes.push(renderValue(key, value.items[key]));
    }
    return m(TreeNode, {left, right: `dict`}, nodes);
  } else {
    const renderButton = (button?: ButtonParams) => {
      if (!button) {
        return null;
      }
      return m(
        'i.material-icons.grey',
        {
          onclick: button.action,
          title: button.hoverText,
        },
        button.icon ?? 'call_made',
      );
    };
    if (value.kind === 'STRING') {
      const right = [
        renderButton(value.leftButton),
        m('span', value.value),
        renderButton(value.rightButton),
      ];
      return m(TreeNode, {left, right});
    } else {
      return null;
    }
  }
}

// Render a given dictionary to a tree.
export function renderDict(dict: Dict): m.Child {
  const rows: m.Children[] = [];
  for (const key of Object.keys(dict.items)) {
    rows.push(renderValue(key, dict.items[key]));
  }
  return m(Tree, rows);
}
