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

import m from 'mithril';
import {inflate} from 'pako';

import {assertTrue} from '../base/logging';
import {isString} from '../base/object_utils';
import {showModal} from '../widgets/modal';

import {globals} from './globals';

const CTRACE_HEADER = 'TRACE:\n';

async function isCtrace(file: File): Promise<boolean> {
  const fileName = file.name.toLowerCase();

  if (fileName.endsWith('.ctrace')) {
    return true;
  }

  // .ctrace files sometimes end with .txt. We can detect these via
  // the presence of TRACE: near the top of the file.
  if (fileName.endsWith('.txt')) {
    const header = await readText(file.slice(0, 128));
    if (header.includes(CTRACE_HEADER)) {
      return true;
    }
  }

  return false;
}

function readText(blob: Blob): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => {
      if (isString(reader.result)) {
        return resolve(reader.result);
      }
    };
    reader.onerror = (err) => {
      reject(err);
    };
    reader.readAsText(blob);
  });
}

export async function isLegacyTrace(file: File): Promise<boolean> {
  const fileName = file.name.toLowerCase();
  if (
    fileName.endsWith('.json') ||
    fileName.endsWith('.json.gz') ||
    fileName.endsWith('.zip') ||
    fileName.endsWith('.html')
  ) {
    return true;
  }

  if (await isCtrace(file)) {
    return true;
  }

  // Sometimes systrace formatted traces end with '.trace'. This is a
  // little generic to assume all such traces are systrace format though
  // so we read the beginning of the file and check to see if is has the
  // systrace header (several comment lines):
  if (fileName.endsWith('.trace')) {
    const header = await readText(file.slice(0, 512));
    const lines = header.split('\n');
    let commentCount = 0;
    for (const line of lines) {
      if (line.startsWith('#')) {
        commentCount++;
      }
    }
    if (commentCount > 5) {
      return true;
    }
  }

  return false;
}

export async function openFileWithLegacyTraceViewer(file: File) {
  const reader = new FileReader();
  reader.onload = () => {
    if (reader.result instanceof ArrayBuffer) {
      return openBufferWithLegacyTraceViewer(
        file.name,
        reader.result,
        reader.result.byteLength,
      );
    } else {
      const str = reader.result as string;
      return openBufferWithLegacyTraceViewer(file.name, str, str.length);
    }
  };
  reader.onerror = (err) => {
    console.error(err);
  };
  if (
    file.name.endsWith('.gz') ||
    file.name.endsWith('.zip') ||
    (await isCtrace(file))
  ) {
    reader.readAsArrayBuffer(file);
  } else {
    reader.readAsText(file);
  }
}

export function openBufferWithLegacyTraceViewer(
  name: string,
  data: ArrayBuffer | string,
  size: number,
) {
  if (data instanceof ArrayBuffer) {
    assertTrue(size <= data.byteLength);
    if (size !== data.byteLength) {
      data = data.slice(0, size);
    }

    // Handle .ctrace files.
    const enc = new TextDecoder('utf-8');
    const header = enc.decode(data.slice(0, 128));
    if (header.includes(CTRACE_HEADER)) {
      const offset = header.indexOf(CTRACE_HEADER) + CTRACE_HEADER.length;
      data = inflate(new Uint8Array(data.slice(offset)), {to: 'string'});
    }
  }

  // The location.pathname mangling is to make this code work also when hosted
  // in a non-root sub-directory, for the case of CI artifacts.
  const catapultUrl = globals.root + 'assets/catapult_trace_viewer.html';
  const newWin = window.open(catapultUrl);
  if (newWin) {
    // Popup succeedeed.
    newWin.addEventListener('load', (e: Event) => {
      const doc = e.target as Document;
      const ctl = doc.querySelector('x-profiling-view') as TraceViewerAPI;
      ctl.setActiveTrace(name, data);
    });
    return;
  }

  // Popup blocker detected.
  showModal({
    title: 'Open trace in the legacy Catapult Trace Viewer',
    content: m(
      'div',
      m('div', 'You are seeing this interstitial because popups are blocked'),
      m('div', 'Enable popups to skip this dialog next time.'),
    ),
    buttons: [
      {
        text: 'Open legacy UI',
        primary: true,
        action: () => openBufferWithLegacyTraceViewer(name, data, size),
      },
    ],
  });
}

// TraceViewer method that we wire up to trigger the file load.
interface TraceViewerAPI extends Element {
  setActiveTrace(name: string, data: ArrayBuffer | string): void;
}
