/*
 * Copyright (C) 2011 Google Inc.  All rights reserved.
 * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
 * Copyright (C) 2009 Joseph Pecoraro
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
Components.JSPresentationUtils = {};

/**
 * @param {?SDK.Target} target
 * @param {!Components.Linkifier} linkifier
 * @param {!Protocol.Runtime.StackTrace=} stackTrace
 * @param {function()=} contentUpdated
 * @return {!Element}
 */
Components.JSPresentationUtils.buildStackTracePreviewContents = function(
    target, linkifier, stackTrace, contentUpdated) {
  const element = createElement('span');
  element.style.display = 'inline-block';
  const shadowRoot = UI.createShadowRootWithCoreStyles(element, 'components/jsUtils.css');
  const contentElement = shadowRoot.createChild('table', 'stack-preview-container');
  const debuggerModel = target ? target.model(SDK.DebuggerModel) : null;
  let totalHiddenCallFramesCount = 0;

  /**
   * @param {!Protocol.Runtime.StackTrace} stackTrace
   * @return {boolean}
   */
  function appendStackTrace(stackTrace) {
    let hiddenCallFrames = 0;
    for (const stackFrame of stackTrace.callFrames) {
      const row = createElement('tr');
      row.createChild('td').textContent = '\n';
      row.createChild('td', 'function-name').textContent = UI.beautifyFunctionName(stackFrame.functionName);
      const link = linkifier.maybeLinkifyConsoleCallFrame(target, stackFrame);
      if (link) {
        link.addEventListener('contextmenu', populateContextMenu.bind(null, link));
        if (debuggerModel) {
          const location = debuggerModel.createRawLocationByScriptId(
              stackFrame.scriptId, stackFrame.lineNumber, stackFrame.columnNumber);
          if (location && Bindings.blackboxManager.isBlackboxedRawLocation(location)) {
            row.classList.add('blackboxed');
            ++hiddenCallFrames;
          }
        }

        row.createChild('td').textContent = ' @ ';
        row.createChild('td').appendChild(link);
      }
      contentElement.appendChild(row);
    }
    totalHiddenCallFramesCount += hiddenCallFrames;
    return stackTrace.callFrames.length === hiddenCallFrames;
  }

  /**
   * @param {!Element} link
   * @param {!Event} event
   */
  function populateContextMenu(link, event) {
    const contextMenu = new UI.ContextMenu(event);
    event.consume(true);
    const uiLocation = Components.Linkifier.uiLocation(link);
    if (uiLocation && Bindings.blackboxManager.canBlackboxUISourceCode(uiLocation.uiSourceCode)) {
      if (Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode)) {
        contextMenu.debugSection().appendItem(
            ls`Stop blackboxing`, () => Bindings.blackboxManager.unblackboxUISourceCode(uiLocation.uiSourceCode));
      } else {
        contextMenu.debugSection().appendItem(
            ls`Blackbox script`, () => Bindings.blackboxManager.blackboxUISourceCode(uiLocation.uiSourceCode));
      }
    }
    contextMenu.appendApplicableItems(event);
    contextMenu.show();
  }

  if (!stackTrace)
    return element;

  appendStackTrace(stackTrace);

  let asyncStackTrace = stackTrace.parent;
  while (asyncStackTrace) {
    if (!asyncStackTrace.callFrames.length) {
      asyncStackTrace = asyncStackTrace.parent;
      continue;
    }
    const row = contentElement.createChild('tr');
    row.createChild('td').textContent = '\n';
    row.createChild('td', 'stack-preview-async-description').textContent =
        UI.asyncStackTraceLabel(asyncStackTrace.description);
    row.createChild('td');
    row.createChild('td');
    if (appendStackTrace(asyncStackTrace))
      row.classList.add('blackboxed');
    asyncStackTrace = asyncStackTrace.parent;
  }

  if (totalHiddenCallFramesCount) {
    const row = contentElement.createChild('tr', 'show-blackboxed-link');
    row.createChild('td').textContent = '\n';
    const cell = row.createChild('td');
    cell.colSpan = 4;
    const showAllLink = cell.createChild('span', 'link');
    if (totalHiddenCallFramesCount === 1)
      showAllLink.textContent = ls`Show 1 more blackboxed frame`;
    else
      showAllLink.textContent = ls`Show ${totalHiddenCallFramesCount} more blackboxed frames`;
    showAllLink.addEventListener('click', () => {
      contentElement.classList.add('show-blackboxed');
      if (contentUpdated)
        contentUpdated();
    }, false);
  }

  return element;
};
