// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
 * @unrestricted
 */
Accessibility.AXNodeSubPane = class extends Accessibility.AccessibilitySubPane {
  constructor() {
    super(ls`Computed Properties`);

    this.contentElement.classList.add('ax-subpane');

    this._noNodeInfo = this.createInfo(ls`No accessibility node`);
    this._ignoredInfo = this.createInfo(ls`Accessibility node not exposed`, 'ax-ignored-info hidden');

    this._treeOutline = this.createTreeOutline();
    this._ignoredReasonsTree = this.createTreeOutline();

    this.element.classList.add('accessibility-computed');
    this.registerRequiredCSS('accessibility/accessibilityNode.css');
  }

  /**
   * @param {?Accessibility.AccessibilityNode} axNode
   * @override
   */
  setAXNode(axNode) {
    if (this._axNode === axNode)
      return;
    this._axNode = axNode;

    const treeOutline = this._treeOutline;
    treeOutline.removeChildren();
    const ignoredReasons = this._ignoredReasonsTree;
    ignoredReasons.removeChildren();

    if (!axNode) {
      treeOutline.element.classList.add('hidden');
      this._ignoredInfo.classList.add('hidden');
      ignoredReasons.element.classList.add('hidden');

      this._noNodeInfo.classList.remove('hidden');
      this.element.classList.add('ax-ignored-node-pane');

      return;
    }

    if (axNode.ignored()) {
      this._noNodeInfo.classList.add('hidden');
      treeOutline.element.classList.add('hidden');
      this.element.classList.add('ax-ignored-node-pane');

      this._ignoredInfo.classList.remove('hidden');
      ignoredReasons.element.classList.remove('hidden');
      /**
       * @param {!Protocol.Accessibility.AXProperty} property
       */
      function addIgnoredReason(property) {
        ignoredReasons.appendChild(new Accessibility.AXNodeIgnoredReasonTreeElement(
            property, /** @type {!Accessibility.AccessibilityNode} */ (axNode)));
      }
      const ignoredReasonsArray = /** @type {!Array<!Protocol.Accessibility.AXProperty>} */ (axNode.ignoredReasons());
      for (const reason of ignoredReasonsArray)
        addIgnoredReason(reason);
      if (!ignoredReasons.firstChild())
        ignoredReasons.element.classList.add('hidden');
      return;
    }
    this.element.classList.remove('ax-ignored-node-pane');

    this._ignoredInfo.classList.add('hidden');
    ignoredReasons.element.classList.add('hidden');
    this._noNodeInfo.classList.add('hidden');

    treeOutline.element.classList.remove('hidden');

    /**
     * @param {!Protocol.Accessibility.AXProperty} property
     */
    function addProperty(property) {
      treeOutline.appendChild(new Accessibility.AXNodePropertyTreePropertyElement(
          property, /** @type {!Accessibility.AccessibilityNode} */ (axNode)));
    }

    for (const property of axNode.coreProperties())
      addProperty(property);

    const roleProperty = /** @type {!Protocol.Accessibility.AXProperty} */ ({name: 'role', value: axNode.role()});
    addProperty(roleProperty);
    for (const property of /** @type {!Array.<!Protocol.Accessibility.AXProperty>} */ (axNode.properties()))
      addProperty(property);
  }

  /**
   * @override
   * @param {?SDK.DOMNode} node
   */
  setNode(node) {
    super.setNode(node);
    this._axNode = null;
  }
};

/**
 * @unrestricted
 */
Accessibility.AXNodePropertyTreeElement = class extends UI.TreeElement {
  /**
   * @param {!Accessibility.AccessibilityNode} axNode
   */
  constructor(axNode) {
    // Pass an empty title, the title gets made later in onattach.
    super('');
    this._axNode = axNode;
  }

  /**
   * @param {?Protocol.Accessibility.AXValueType} type
   * @param {string} value
   * @return {!Element}
   */
  static createSimpleValueElement(type, value) {
    let valueElement;
    const AXValueType = Protocol.Accessibility.AXValueType;
    if (!type || type === AXValueType.ValueUndefined || type === AXValueType.ComputedString)
      valueElement = createElement('span');
    else
      valueElement = createElementWithClass('span', 'monospace');
    let valueText;
    const isStringProperty = type && Accessibility.AXNodePropertyTreeElement.StringProperties.has(type);
    if (isStringProperty) {
      // Render \n as a nice unicode cr symbol.
      valueText = '"' + value.replace(/\n/g, '\u21B5') + '"';
      valueElement._originalTextContent = value;
    } else {
      valueText = String(value);
    }

    if (type && type in Accessibility.AXNodePropertyTreeElement.TypeStyles)
      valueElement.classList.add(Accessibility.AXNodePropertyTreeElement.TypeStyles[type]);

    valueElement.setTextContentTruncatedIfNeeded(valueText || '');

    valueElement.title = String(value) || '';

    return valueElement;
  }

  /**
   * @param {string} tooltip
   * @return {!Element}
   */
  static createExclamationMark(tooltip) {
    const exclamationElement = createElement('span', 'dt-icon-label');
    exclamationElement.type = 'smallicon-warning';
    exclamationElement.title = tooltip;
    return exclamationElement;
  }

  /**
   * @param {string} name
   */
  appendNameElement(name) {
    const nameElement = createElement('span');
    const AXAttributes = Accessibility.AccessibilityStrings.AXAttributes;
    if (name in AXAttributes) {
      nameElement.textContent = ls(AXAttributes[name].name);
      nameElement.title = AXAttributes[name].description;
      nameElement.classList.add('ax-readable-name');
    } else {
      nameElement.textContent = name;
      nameElement.classList.add('ax-name');
      nameElement.classList.add('monospace');
    }
    this.listItemElement.appendChild(nameElement);
  }

  /**
   * @param {!Protocol.Accessibility.AXValue} value
   */
  appendValueElement(value) {
    const AXValueType = Protocol.Accessibility.AXValueType;
    if (value.type === AXValueType.Idref || value.type === AXValueType.Node || value.type === AXValueType.IdrefList ||
        value.type === AXValueType.NodeList) {
      this.appendRelatedNodeListValueElement(value);
      return;
    } else if (value.sources) {
      const sources = value.sources;
      for (let i = 0; i < sources.length; i++) {
        const source = sources[i];
        const child = new Accessibility.AXValueSourceTreeElement(source, this._axNode);
        this.appendChild(child);
      }
      this.expand();
    }
    const element = Accessibility.AXNodePropertyTreeElement.createSimpleValueElement(value.type, String(value.value));
    this.listItemElement.appendChild(element);
  }

  /**
   * @param {!Protocol.Accessibility.AXRelatedNode} relatedNode
   * @param {number} index
   */
  appendRelatedNode(relatedNode, index) {
    const deferredNode =
        new SDK.DeferredDOMNode(this._axNode.accessibilityModel().target(), relatedNode.backendDOMNodeId);
    const nodeTreeElement = new Accessibility.AXRelatedNodeSourceTreeElement({deferredNode: deferredNode}, relatedNode);
    this.appendChild(nodeTreeElement);
  }

  /**
   * @param {!Protocol.Accessibility.AXRelatedNode} relatedNode
   */
  appendRelatedNodeInline(relatedNode) {
    const deferredNode =
        new SDK.DeferredDOMNode(this._axNode.accessibilityModel().target(), relatedNode.backendDOMNodeId);
    const linkedNode = new Accessibility.AXRelatedNodeElement({deferredNode: deferredNode}, relatedNode);
    this.listItemElement.appendChild(linkedNode.render());
  }

  /**
   * @param {!Protocol.Accessibility.AXValue} value
   */
  appendRelatedNodeListValueElement(value) {
    if (value.relatedNodes.length === 1 && !value.value) {
      this.appendRelatedNodeInline(value.relatedNodes[0]);
      return;
    }

    value.relatedNodes.forEach(this.appendRelatedNode, this);
    if (value.relatedNodes.length <= 3)
      this.expand();
    else
      this.collapse();
  }
};


/** @type {!Object<string, string>} */
Accessibility.AXNodePropertyTreeElement.TypeStyles = {
  attribute: 'ax-value-string',
  boolean: 'object-value-boolean',
  booleanOrUndefined: 'object-value-boolean',
  computedString: 'ax-readable-string',
  idref: 'ax-value-string',
  idrefList: 'ax-value-string',
  integer: 'object-value-number',
  internalRole: 'ax-internal-role',
  number: 'ax-value-number',
  role: 'ax-role',
  string: 'ax-value-string',
  tristate: 'object-value-boolean',
  valueUndefined: 'ax-value-undefined'
};

/** @type {!Set.<!Protocol.Accessibility.AXValueType>} */
Accessibility.AXNodePropertyTreeElement.StringProperties = new Set([
  Protocol.Accessibility.AXValueType.String, Protocol.Accessibility.AXValueType.ComputedString,
  Protocol.Accessibility.AXValueType.IdrefList, Protocol.Accessibility.AXValueType.Idref
]);

/**
 * @unrestricted
 */
Accessibility.AXNodePropertyTreePropertyElement = class extends Accessibility.AXNodePropertyTreeElement {
  /**
   * @param {!Protocol.Accessibility.AXProperty} property
   * @param {!Accessibility.AccessibilityNode} axNode
   */
  constructor(property, axNode) {
    super(axNode);

    this._property = property;
    this.toggleOnClick = true;
    this.selectable = false;

    this.listItemElement.classList.add('property');
  }

  /**
   * @override
   */
  onattach() {
    this._update();
  }

  _update() {
    this.listItemElement.removeChildren();

    this.appendNameElement(this._property.name);

    this.listItemElement.createChild('span', 'separator').textContent = ':\u00A0';

    this.appendValueElement(this._property.value);
  }
};

/**
 * @unrestricted
 */
Accessibility.AXValueSourceTreeElement = class extends Accessibility.AXNodePropertyTreeElement {
  /**
   * @param {!Protocol.Accessibility.AXValueSource} source
   * @param {!Accessibility.AccessibilityNode} axNode
   */
  constructor(source, axNode) {
    super(axNode);
    this._source = source;
    this.selectable = false;
  }

  /**
   * @override
   */
  onattach() {
    this._update();
  }

  /**
   * @param {!Protocol.Accessibility.AXRelatedNode} relatedNode
   * @param {number} index
   * @param {string} idref
   */
  appendRelatedNodeWithIdref(relatedNode, index, idref) {
    const deferredNode =
        new SDK.DeferredDOMNode(this._axNode.accessibilityModel().target(), relatedNode.backendDOMNodeId);
    const nodeTreeElement =
        new Accessibility.AXRelatedNodeSourceTreeElement({deferredNode: deferredNode, idref: idref}, relatedNode);
    this.appendChild(nodeTreeElement);
  }

  /**
   * @param {!Protocol.Accessibility.AXValue} value
   */
  appendIDRefValueElement(value) {
    const relatedNodes = value.relatedNodes;

    const idrefs = value.value.trim().split(/\s+/);
    if (idrefs.length === 1) {
      const idref = idrefs[0];
      const matchingNode = relatedNodes.find(node => node.idref === idref);
      if (matchingNode)
        this.appendRelatedNodeWithIdref(matchingNode, 0, idref);
      else
        this.listItemElement.appendChild(new Accessibility.AXRelatedNodeElement({idref: idref}).render());

    } else {
      // TODO(aboxhall): exclamation mark if not idreflist type
      for (let i = 0; i < idrefs.length; ++i) {
        const idref = idrefs[i];
        const matchingNode = relatedNodes.find(node => node.idref === idref);
        if (matchingNode)
          this.appendRelatedNodeWithIdref(matchingNode, i, idref);
        else
          this.appendChild(new Accessibility.AXRelatedNodeSourceTreeElement({idref: idref}));
      }
    }
  }

  /**
   * @param {!Protocol.Accessibility.AXValue} value
   * @override
   */
  appendRelatedNodeListValueElement(value) {
    const relatedNodes = value.relatedNodes;
    const numNodes = relatedNodes.length;

    if (value.type === Protocol.Accessibility.AXValueType.IdrefList ||
        value.type === Protocol.Accessibility.AXValueType.Idref)
      this.appendIDRefValueElement(value);
    else
      super.appendRelatedNodeListValueElement(value);


    if (numNodes <= 3)
      this.expand();
    else
      this.collapse();
  }

  /**
   * @param {!Protocol.Accessibility.AXValueSource} source
   */
  appendSourceNameElement(source) {
    const nameElement = createElement('span');
    const AXValueSourceType = Protocol.Accessibility.AXValueSourceType;
    const type = source.type;
    switch (type) {
      case AXValueSourceType.Attribute:
      case AXValueSourceType.Placeholder:
      case AXValueSourceType.RelatedElement:
        if (source.nativeSource) {
          const AXNativeSourceTypes = Accessibility.AccessibilityStrings.AXNativeSourceTypes;
          const nativeSource = source.nativeSource;
          nameElement.textContent = ls(AXNativeSourceTypes[nativeSource].name);
          nameElement.title = ls(AXNativeSourceTypes[nativeSource].description);
          nameElement.classList.add('ax-readable-name');
          break;
        }
        nameElement.textContent = source.attribute;
        nameElement.classList.add('ax-name');
        nameElement.classList.add('monospace');
        break;
      default:
        const AXSourceTypes = Accessibility.AccessibilityStrings.AXSourceTypes;
        if (type in AXSourceTypes) {
          nameElement.textContent = ls(AXSourceTypes[type].name);
          nameElement.title = ls(AXSourceTypes[type].description);
          nameElement.classList.add('ax-readable-name');
        } else {
          console.warn(type, 'not in AXSourceTypes');
          nameElement.textContent = ls(type);
        }
    }
    this.listItemElement.appendChild(nameElement);
  }

  _update() {
    this.listItemElement.removeChildren();

    if (this._source.invalid) {
      const exclamationMark = Accessibility.AXNodePropertyTreeElement.createExclamationMark(ls`Invalid source.`);
      this.listItemElement.appendChild(exclamationMark);
      this.listItemElement.classList.add('ax-value-source-invalid');
    } else if (this._source.superseded) {
      this.listItemElement.classList.add('ax-value-source-unused');
    }

    this.appendSourceNameElement(this._source);

    this.listItemElement.createChild('span', 'separator').textContent = ':\u00a0';

    if (this._source.attributeValue) {
      this.appendValueElement(this._source.attributeValue);
      this.listItemElement.createTextChild('\u00a0');
    } else if (this._source.nativeSourceValue) {
      this.appendValueElement(this._source.nativeSourceValue);
      this.listItemElement.createTextChild('\u00a0');
      if (this._source.value)
        this.appendValueElement(this._source.value);
    } else if (this._source.value) {
      this.appendValueElement(this._source.value);
    } else {
      const valueElement = Accessibility.AXNodePropertyTreeElement.createSimpleValueElement(
          Protocol.Accessibility.AXValueType.ValueUndefined, ls`Not specified`);
      this.listItemElement.appendChild(valueElement);
      this.listItemElement.classList.add('ax-value-source-unused');
    }

    if (this._source.value && this._source.superseded)
      this.listItemElement.classList.add('ax-value-source-superseded');
  }
};

/**
 * @unrestricted
 */
Accessibility.AXRelatedNodeSourceTreeElement = class extends UI.TreeElement {
  /**
   * @param {{deferredNode: (!SDK.DeferredDOMNode|undefined), idref: (string|undefined)}} node
   * @param {!Protocol.Accessibility.AXRelatedNode=} value
   */
  constructor(node, value) {
    super('');

    this._value = value;
    this._axRelatedNodeElement = new Accessibility.AXRelatedNodeElement(node, value);
    this.selectable = false;
  }

  /**
   * @override
   */
  onattach() {
    this.listItemElement.appendChild(this._axRelatedNodeElement.render());
    if (!this._value)
      return;

    if (this._value.text) {
      this.listItemElement.appendChild(Accessibility.AXNodePropertyTreeElement.createSimpleValueElement(
          Protocol.Accessibility.AXValueType.ComputedString, this._value.text));
    }
  }
};

/**
 * @unrestricted
 */
Accessibility.AXRelatedNodeElement = class {
  /**
   * @param {{deferredNode: (!SDK.DeferredDOMNode|undefined), idref: (string|undefined)}} node
   * @param {!Protocol.Accessibility.AXRelatedNode=} value
   */
  constructor(node, value) {
    this._deferredNode = node.deferredNode;
    this._idref = node.idref;
    this._value = value;
  }

  /**
   * @return {!Element}
   */
  render() {
    const element = createElement('span');
    let valueElement;

    if (this._deferredNode) {
      valueElement = createElement('span');
      element.appendChild(valueElement);
      Common.Linkifier.linkify(this._deferredNode).then(linkfied => valueElement.appendChild(linkfied));
    } else if (this._idref) {
      element.classList.add('invalid');
      valueElement = Accessibility.AXNodePropertyTreeElement.createExclamationMark(ls`No node with this ID.`);
      valueElement.createTextChild(this._idref);
      element.appendChild(valueElement);
    }

    return element;
  }
};

/**
 * @unrestricted
 */
Accessibility.AXNodeIgnoredReasonTreeElement = class extends Accessibility.AXNodePropertyTreeElement {
  /**
   * @param {!Protocol.Accessibility.AXProperty} property
   * @param {!Accessibility.AccessibilityNode} axNode
   */
  constructor(property, axNode) {
    super(axNode);
    this._property = property;
    this._axNode = axNode;
    this.toggleOnClick = true;
    this.selectable = false;
  }

  /**
   * @param {?string} reason
   * @param {?Accessibility.AccessibilityNode} axNode
   * @return {?Element}
   */
  static createReasonElement(reason, axNode) {
    let reasonElement = null;
    switch (reason) {
      case 'activeModalDialog':
        reasonElement = UI.formatLocalized('Element is hidden by active modal dialog:\u00a0', []);
        break;
      case 'ancestorIsLeafNode':
        reasonElement = UI.formatLocalized('Ancestor\'s children are all presentational:\u00a0', []);
        break;
      case 'ariaHiddenElement': {
        const ariaHiddenSpan = createElement('span', 'source-code').textContent = 'aria-hidden';
        reasonElement = UI.formatLocalized('Element is %s.', [ariaHiddenSpan]);
        break;
      }
      case 'ariaHiddenSubtree': {
        const ariaHiddenSpan = createElement('span', 'source-code').textContent = 'aria-hidden';
        const trueSpan = createElement('span', 'source-code').textContent = 'true';
        reasonElement = UI.formatLocalized('%s is %s on ancestor:\u00a0', [ariaHiddenSpan, trueSpan]);
        break;
      }
      case 'emptyAlt':
        reasonElement = UI.formatLocalized('Element has empty alt text.', []);
        break;
      case 'emptyText':
        reasonElement = UI.formatLocalized('No text content.', []);
        break;
      case 'inertElement':
        reasonElement = UI.formatLocalized('Element is inert.', []);
        break;
      case 'inertSubtree':
        reasonElement = UI.formatLocalized('Element is in an inert subtree from\u00a0', []);
        break;
      case 'inheritsPresentation':
        reasonElement = UI.formatLocalized('Element inherits presentational role from\u00a0', []);
        break;
      case 'labelContainer':
        reasonElement = UI.formatLocalized('Part of label element:\u00a0', []);
        break;
      case 'labelFor':
        reasonElement = UI.formatLocalized('Label for\u00a0', []);
        break;
      case 'notRendered':
        reasonElement = UI.formatLocalized('Element is not rendered.', []);
        break;
      case 'notVisible':
        reasonElement = UI.formatLocalized('Element is not visible.', []);
        break;
      case 'presentationalRole': {
        const rolePresentationSpan = createElement('span', 'source-code').textContent = 'role=' + axNode.role().value;
        reasonElement = UI.formatLocalized('Element has %s.', [rolePresentationSpan]);
        break;
      }
      case 'probablyPresentational':
        reasonElement = UI.formatLocalized('Element is presentational.', []);
        break;
      case 'staticTextUsedAsNameFor':
        reasonElement = UI.formatLocalized('Static text node is used as name for\u00a0', []);
        break;
      case 'uninteresting':
        reasonElement = UI.formatLocalized('Element not interesting for accessibility.', []);
        break;
    }
    if (reasonElement)
      reasonElement.classList.add('ax-reason');
    return reasonElement;
  }

  /**
   * @override
   */
  onattach() {
    this.listItemElement.removeChildren();

    this._reasonElement =
        Accessibility.AXNodeIgnoredReasonTreeElement.createReasonElement(this._property.name, this._axNode);
    this.listItemElement.appendChild(this._reasonElement);

    const value = this._property.value;
    if (value.type === Protocol.Accessibility.AXValueType.Idref)
      this.appendRelatedNodeListValueElement(value);
  }
};
