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

// Helper function to create DOM elements faster: takes a Mithril-style
// "selector" of the form "tag.class1.class2" and a list of child objects that
// can be either strings or DOM elements.
function m(selector, ...children) {
  const parts = selector.split('.');
  if (parts.length === 0) {
    throw new Error(
      'Selector passed to element should be of a form tag.class1.class2');
  }

  const result = document.createElement(parts[0]);
  for (let i = 1; i < parts.length; i++) {
    result.classList.add(parts[i]);
  }
  for (const child of children) {
    if (typeof child === 'string') {
      const childNode = document.createTextNode(child);
      result.appendChild(childNode);
    } else {
      result.appendChild(child);
    }
  }
  return result;
}

function getCiRun() {
  const url = new URL(window.location.href);
  const parts = url.pathname.split('/');

  // Example report URL:
  // https://storage.googleapis.com/perfetto-ci-artifacts/20220711123401--cls-2149676-1--ui-clang-x86_64-release/ui-test-artifacts/index.html
  // Parts would contain ['', 'perfetto-ci-artifacts',
  // '20220711123401--cls-2149676-1--ui-clang-x86_64-release', ...] in this
  // case, which means that we need to check length of the array and get third
  // element out of it.
  if (parts.length >= 3) {
    return parts[2];
  }
  return null;
}

function imageLinkElement(path) {
  const img = m('img');
  img.src = path;
  const link = m('a');
  link.appendChild(img);
  link.href = path;
  link.target = '_blank';
  return link;
}

function processLines(lines) {
  const container = document.querySelector('.container');
  container.innerHTML = '';
  const children = [];

  // report.txt is a text file with a pair of file names on each line, separated
  // by semicolon. E.g. "screenshot.png;screenshot-diff.png"
  for (const line of lines) {
    // Skip empty lines (happens when the file is completely empty).
    if (line.length === 0) {
      continue;
    }

    const parts = line.split(';');
    if (parts.length !== 2) {
      console.warn(
        `Malformed line (expected two files separated via semicolon) ${
          line}!`);
      continue;
    }

    const [output, diff] = parts;
    children.push(m(
      'div.row',
      m('div.cell', output, m('div.image-wrapper', imageLinkElement(output))),
      m('div.cell', diff, m('div.image-wrapper', imageLinkElement(diff)))));
  }

  if (children.length === 0) {
    container.appendChild(m('div', 'All good!'));
    return;
  }

  const run = getCiRun();

  if (run !== null) {
    const cmd = `tools/download_changed_screenshots.py ${run}`;
    const button = m('button', 'Copy');
    button.addEventListener('click', async () => {
      await navigator.clipboard.writeText(cmd);
      button.innerText = 'Copied!';
    });

    container.appendChild(m(
      'div.message',
      'Use following command from Perfetto checkout directory to apply the ' +
            'changes: ',
      m('span.cmd', cmd),
      button));
  }

  for (const child of children) {
    container.appendChild(child);
  }
}

async function loadDiffs() {
  try {
    const report = await fetch('report.txt');
    const response = await report.text();
    processLines(response.split('\n'));
  } catch (e) {
    // report.txt is not available when all tests have succeeded, treat fetching
    // error as absence of failures
    processLines([]);
  }
}

document.addEventListener('DOMContentLoaded', () => {
  loadDiffs();
});
