// Copyright (C) 2020 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.

'use strict';

let tocAnchors = [];
let lastMouseOffY = 0;
let onloadFired = false;
const postLoadActions = [];
let tocEventHandlersInstalled = false;
let resizeObserver = undefined;

function doAfterLoadEvent(action) {
  if (onloadFired) {
    return action();
  }
  postLoadActions.push(action);
}

function setupSandwichMenu() {
  const header = document.querySelector('.site-header');
  const docsNav = document.querySelector('.nav');
  const menu = header.querySelector('.menu');
  menu.addEventListener('click', (e) => {
    e.preventDefault();

    // If we are displaying any /docs, toggle the navbar instead (the TOC).
    if (docsNav) {
      // |after_first_click| is to avoid spurious transitions on page load.
      docsNav.classList.add('after_first_click');
      updateNav();
      setTimeout(() => docsNav.classList.toggle('expanded'), 0);
    } else {
      header.classList.toggle('expanded');
    }
  });
}

// (Re-)Generates the Table Of Contents for docs (the right-hand-side one).
function updateTOC() {
  const tocContainer = document.querySelector('.docs .toc');
  if (!tocContainer)
    return;
  const toc = document.createElement('ul');
  const anchors = document.querySelectorAll('.doc a.anchor');
  tocAnchors = [];
  for (const anchor of anchors) {
    const li = document.createElement('li');
    const link = document.createElement('a');
    link.innerText = anchor.parentElement.innerText;
    link.href = anchor.href;
    link.onclick = () => {
      onScroll(link)
    };
    li.appendChild(link);
    if (anchor.parentElement.tagName === 'H3')
      li.style.paddingLeft = '10px';
    toc.appendChild(li);
    doAfterLoadEvent(() => {
      tocAnchors.push(
        { top: anchor.offsetTop + anchor.offsetHeight / 2, obj: link });
    });
  }
  tocContainer.innerHTML = '';
  tocContainer.appendChild(toc);

  // Add event handlers on the first call (can be called more than once to
  // recompute anchors on resize).
  if (tocEventHandlersInstalled)
    return;
  tocEventHandlersInstalled = true;
  const doc = document.querySelector('.doc');
  const passive = { passive: true };
  if (doc) {
    const offY = doc.offsetTop;
    doc.addEventListener('mousemove', (e) => onMouseMove(offY, e), passive);
    doc.addEventListener('mouseleave', () => {
      lastMouseOffY = 0;
    }, passive);
  }
  window.addEventListener('scroll', () => onScroll(), passive);
  resizeObserver = new ResizeObserver(() => requestAnimationFrame(() => {
    updateNav();
    updateTOC();
  }));
  resizeObserver.observe(doc);
}

// Highlights the current TOC anchor depending on the scroll offset.
function onMouseMove(offY, e) {
  lastMouseOffY = e.clientY - offY;
  onScroll();
}

function onScroll(forceHighlight) {
  const y = document.documentElement.scrollTop + lastMouseOffY;
  let highEl = undefined;
  for (const x of tocAnchors) {
    if (y < x.top)
      continue;
    highEl = x.obj;
  }
  for (const link of document.querySelectorAll('.docs .toc a')) {
    if ((!forceHighlight && link === highEl) || (forceHighlight === link)) {
      link.classList.add('highlighted');
    } else {
      link.classList.remove('highlighted');
    }
  }
}

// This function needs to be idempotent as it is called more than once (on every
// resize).
function updateNav() {
  const curDoc = document.querySelector('.doc');
  let curFileName = '';
  if (curDoc)
    curFileName = curDoc.dataset['mdFile'];

  // First identify all the top-level nav entries (Quickstart, Data Sources,
  // ...) and make them compressible.
  const toplevelSections = document.querySelectorAll('.docs .nav > ul > li');
  const toplevelLinks = [];
  for (const sec of toplevelSections) {
    const childMenu = sec.querySelector('ul');
    if (!childMenu) {
      // Don't make it compressible if it has no children (e.g. the very
      // first 'Introduction' link).
      continue;
    }

    // Don't make it compressible if the entry has an actual link (e.g. the very
    // first 'Introduction' link), because otherwise it become ambiguous whether
    // the link should toggle or open the link.
    const link = sec.querySelector('a');
    if (!link || !link.href.endsWith('#'))
      continue;

    sec.classList.add('compressible');

    // Remember the compressed status as long as the page is opened, so clicking
    // through links keeps the sidebar in a consistent visual state.
    const memoKey = `docs.nav.compressed[${link.innerHTML}]`;

    if (sessionStorage.getItem(memoKey) === '1') {
      sec.classList.add('compressed');
    }
    doAfterLoadEvent(() => {
      childMenu.style.maxHeight = `${childMenu.scrollHeight + 40}px`;
    });

    toplevelLinks.push(link);
    link.onclick = (evt) => {
      evt.preventDefault();
      sec.classList.toggle('compressed');
      if (sec.classList.contains('compressed')) {
        sessionStorage.setItem(memoKey, '1');
      } else {
        sessionStorage.removeItem(memoKey);
      }
    };
  }

  const exps = document.querySelectorAll('.docs .nav ul a');
  let found = false;
  for (const x of exps) {
    // If the url of the entry matches the url of the page, mark the item as
    // highlighted and expand all its parents.
    if (!x.href)
      continue;
    const url = new URL(x.href);
    if (x.href.endsWith('#')) {
      // This is a non-leaf link to a menu.
      if (toplevelLinks.indexOf(x) < 0) {
        x.removeAttribute('href');
      }
    } else if (url.pathname === curFileName && !found) {
      x.classList.add('selected');
      doAfterLoadEvent(() => x.scrollIntoViewIfNeeded());
      found = true;  // Highlight only the first occurrence.
    }
  }
}

// If the page contains a ```mermaid ``` block, lazily loads the plugin and
// renders.
function initMermaid() {
  const graphs = document.querySelectorAll('.mermaid');

  // Skip if there are no mermaid graphs to render.
  if (!graphs.length)
    return;

  const script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = '/assets/mermaid.min.js';
  const themeCSS = `
  .cluster rect { fill: #FCFCFC; stroke: #ddd }
  .node rect { fill: #DCEDC8; stroke: #8BC34A}
  .edgeLabel:not(:empty) {
      border-radius: 6px;
      font-size: 0.9em;
      padding: 4px;
      background: #F5F5F5;
      border: 1px solid #DDDDDD;
      color: #666;
  }
  `;
  script.addEventListener('load', () => {
    mermaid.initialize({
      startOnLoad: false,
      themeCSS: themeCSS,
      securityLevel: 'loose',  // To allow #in-page-links
    });
    for (const graph of graphs) {
      requestAnimationFrame(() => {
        mermaid.init(undefined, graph);
        graph.classList.add('rendered');
      });
    }
  })
  document.body.appendChild(script);
}

function setupSearch() {
  const URL =
    'https://www.googleapis.com/customsearch/v1?key=AIzaSyBTD2XJkQkkuvDn76LSftsgWOkdBz9Gfwo&cx=007128963598137843411:8suis14kcmy&q='
  const searchContainer = document.getElementById('search');
  const searchBox = document.getElementById('search-box');
  const searchRes = document.getElementById('search-res')
  if (!searchBox || !searchRes) return;

  document.body.addEventListener('keydown', (e) => {
    if (e.key === '/' && e.target.tagName.toLowerCase() === 'body') {
      searchBox.setSelectionRange(0, -1);
      searchBox.focus();
      e.preventDefault();
    } else if (e.key === 'Escape' && searchContainer.contains(e.target)) {
      searchBox.blur();

      // Handle the case of clicking Tab and moving down to results.
      e.target.blur();
    }
  });

  let timerId = -1;
  let lastSearchId = 0;

  const doSearch = async () => {
    timerId = -1;
    searchRes.style.width = `${searchBox.offsetWidth}px`;

    // `searchId` handles the case of two subsequent requests racing. This is to
    // prevent older results, delivered in reverse order, to replace newer ones.
    const searchId = ++lastSearchId;
    const f = await fetch(URL + encodeURIComponent(searchBox.value));
    const jsonRes = await f.json();
    const results = jsonRes['items'];
    searchRes.innerHTML = '';
    if (results === undefined || searchId != lastSearchId) {
      return;
    }
    for (const res of results) {
      const link = document.createElement('a');
      link.href = res.link;
      const title = document.createElement('div');
      title.className = 'sr-title';
      title.innerText = res.title.replace(' - Perfetto Tracing Docs', '');
      link.appendChild(title);

      const snippet = document.createElement('div');
      snippet.className = 'sr-snippet';
      snippet.innerText = res.snippet;
      link.appendChild(snippet);

      const div = document.createElement('div');
      div.appendChild(link);
      searchRes.appendChild(div);
    }
  };

  searchBox.addEventListener('keyup', () => {
    if (timerId >= 0) return;
    timerId = setTimeout(doSearch, 200);
  });
}

window.addEventListener('DOMContentLoaded', () => {
  updateNav();
  updateTOC();
});

window.addEventListener('load', () => {
  setupSandwichMenu();
  initMermaid();

  // Don't smooth-scroll on pages that are too long (e.g. reference pages).
  if (document.body.scrollHeight < 10000) {
    document.documentElement.style.scrollBehavior = 'smooth';
  } else {
    document.documentElement.style.scrollBehavior = 'initial';
  }

  onloadFired = true;
  while (postLoadActions.length > 0) {
    postLoadActions.shift()();
  }

  updateTOC();
  setupSearch();

  // Enable animations only after the load event. This is to prevent glitches
  // when switching pages.
  document.documentElement.style.setProperty('--anim-enabled', '1')
});

// Handles redirects from the old docs.perfetto.dev.
const legacyRedirectMap = {
  '#/contributing': '/docs/contributing/getting-started#community',
  '#/build-instructions': '/docs/contributing/build-instructions',
  '#/testing': '/docs/contributing/testing',
  '#/app-instrumentation': '/docs/instrumentation/tracing-sdk',
  '#/recording-traces': '/docs/instrumentation/tracing-sdk#recording',
  '#/running': '/docs/quickstart/android-tracing',
  '#/long-traces': '/docs/concepts/config#long-traces',
  '#/detached-mode': '/docs/concepts/detached-mode',
  '#/heapprofd': '/docs/data-sources/native-heap-profiler',
  '#/java-hprof': '/docs/data-sources/java-heap-profiler',
  '#/trace-processor': '/docs/analysis/trace-processor',
  '#/analysis': '/docs/analysis/trace-processor#annotations',
  '#/metrics': '/docs/analysis/metrics',
  '#/traceconv': '/docs/quickstart/traceconv',
  '#/clock-sync': '/docs/concepts/clock-sync',
  '#/architecture': '/docs/concepts/service-model',
};

const fragment = location.hash.split('?')[0].replace('.md', '');
if (fragment in legacyRedirectMap) {
  location.replace(legacyRedirectMap[fragment]);
}

// Pages which have been been removed/renamed/moved and need to be redirected
// to their new home.
const redirectMap = {
  // stdlib docs is not a perfect replacement but is good enough until we write
  // a proper, Android specific query codelab page.
  // TODO(lalitm): switch to that page when it's ready.
  '/docs/analysis/common-queries': '/docs/analysis/stdlib-docs',
};

if (location.pathname in redirectMap) {
  location.replace(redirectMap[location.pathname]);
}
