// 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 '../widgets/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);
}
