// Copyright (C) 2021 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 {Actions} from '../common/actions';
import {tryGetTrace} from '../common/cache_manager';
import {showModal} from '../widgets/modal';

import {loadAndroidBugToolInfo} from './android_bug_tool';
import {globals} from './globals';
import {Route, Router} from './router';
import {taskTracker} from './task_tracker';

function getCurrentTraceUrl(): undefined|string {
  const source = globals.getCurrentEngine()?.source;
  if (source && source.type === 'URL') {
    return source.url;
  }
  return undefined;
}

export function maybeOpenTraceFromRoute(route: Route) {
  if (route.args.s) {
    // /?s=xxxx for permalinks.
    globals.dispatch(Actions.loadPermalink({hash: route.args.s}));
    return;
  }

  const url = route.args.url;
  if (url && url !== getCurrentTraceUrl()) {
    // /?url=https://commondatastorage.googleapis.com/bucket/trace
    // This really works only for GCS because the Content Security Policy
    // forbids any other url.
    loadTraceFromUrl(url);
    return;
  }

  if (route.args.openFromAndroidBugTool) {
    // Handles interaction with the Android Bug Tool extension. See b/163421158.
    openTraceFromAndroidBugTool();
    return;
  }

  if (route.args.p && route.page === '/record') {
    // Handles backwards compatibility for old URLs (linked from various docs),
    // generated before we switched URL scheme. e.g., 'record?p=power' vs
    // 'record/power'. See b/191255021#comment2.
    Router.navigate(`#!/record/${route.args.p}`);
    return;
  }

  if (route.args.local_cache_key) {
    // Handles the case of loading traces from the cache storage.
    maybeOpenCachedTrace(route.args.local_cache_key);
    return;
  }
}


/*
 * openCachedTrace(uuid) is called: (1) on startup, from frontend/index.ts; (2)
 * every time the fragment changes (from Router.onRouteChange).
 * This function must be idempotent (imagine this is called on every frame).
 * It must take decision based on the app state, not on URL change events.
 * Fragment changes are handled by the union of Router.onHashChange() and this
 * function, as follows:
 * 1. '' -> URL without a ?local_cache_key=xxx arg:
 *  - no effect (except redrawing)
 * 2. URL without local_cache_key -> URL with local_cache_key:
 *  - Load cached trace (without prompting any dialog).
 *  - Show a (graceful) error dialog in the case of cache misses.
 * 3. '' -> URL with a ?local_cache_key=xxx arg:
 *  - Same as case 2.
 * 4. URL with local_cache_key=1 -> URL with local_cache_key=2:
 *  a) If 2 != uuid of the trace currently loaded (globals.state.traceUuid):
 *  - Ask the user if they intend to switch trace and load 2.
 *  b) If 2 == uuid of current trace (e.g., after a new trace has loaded):
 *  - no effect (except redrawing).
 * 5. URL with local_cache_key -> URL without local_cache_key:
 *  - Redirect to ?local_cache_key=1234 where 1234 is the UUID of the previous
 *    URL (this might or might not match globals.state.traceUuid).
 *
 * Backward navigation cases:
 * 6. URL without local_cache_key <- URL with local_cache_key:
 *  - Same as case 5.
 * 7. URL with local_cache_key=1 <- URL with local_cache_key=2:
 *  - Same as case 4a: go back to local_cache_key=1 but ask the user to confirm.
 * 8. landing page <- URL with local_cache_key:
 *  - Same as case 5: re-append the local_cache_key.
 */
async function maybeOpenCachedTrace(traceUuid: string) {
  if (traceUuid === globals.state.traceUuid) {
    // Do nothing, matches the currently loaded trace.
    return;
  }

  if (traceUuid === '') {
    // This can happen if we switch from an empty UI state to an invalid UUID
    // (e.g. due to a cache miss, below). This can also happen if the user just
    // types /#!/viewer?local_cache_key=.
    return;
  }

  // This handles the case when a trace T1 is loaded and then the url is set to
  // ?local_cache_key=T2. In that case globals.state.traceUuid remains set to T1
  // until T2 has been loaded by the trace processor (can take several seconds).
  // This early out prevents to re-trigger the openTraceFromXXX() action if the
  // URL changes (e.g. if the user navigates back/fwd) while the new trace is
  // being loaded.
  if (globals.state.engine !== undefined) {
    const eng = globals.state.engine;
    if (eng.source.type === 'ARRAY_BUFFER' && eng.source.uuid === traceUuid) {
      return;
    }
  }

  // Fetch the trace from the cache storage. If available load it. If not, show
  // a dialog informing the user about the cache miss.
  const maybeTrace = await tryGetTrace(traceUuid);

  const navigateToOldTraceUuid = () => {
    Router.navigate(
      `#!/viewer?local_cache_key=${globals.state.traceUuid || ''}`);
  };

  if (!maybeTrace) {
    showModal({
      title: 'Could not find the trace in the cache storage',
      content: m(
        'div',
        m('p',
          'You are trying to load a cached trace by setting the ' +
                '?local_cache_key argument in the URL.'),
        m('p', 'Unfortunately the trace wasn\'t in the cache storage.'),
        m('p',
          'This can happen if a tab was discarded and wasn\'t opened ' +
                'for too long, or if you just mis-pasted the URL.'),
        m('pre', `Trace UUID: ${traceUuid}`),
      ),
    });
    navigateToOldTraceUuid();
    return;
  }

  // If the UI is in a blank state (no trace has been ever opened), just load
  // the trace without showing any further dialog. This is the case of tab
  // discarding, reloading or pasting a url with a local_cache_key in an empty
  // instance.
  if (globals.state.traceUuid === undefined) {
    globals.dispatch(Actions.openTraceFromBuffer(maybeTrace));
    return;
  }

  // If, instead, another trace is loaded, ask confirmation to the user.
  // Switching to another trace clears the UI state. It can be quite annoying to
  // lose the UI state by accidentally navigating back too much.
  let hasOpenedNewTrace = false;

  await showModal({
    title: 'You are about to load a different trace and reset the UI state',
    content: m(
      'div',
      m('p',
        'You are seeing this because you either pasted a URL with ' +
              'a different ?local_cache_key=xxx argument or because you hit ' +
              'the history back/fwd button and reached a different trace.'),
      m('p',
        'If you continue another trace will be loaded and the UI ' +
              'state will be cleared.'),
      m('pre',
        `Old trace: ${globals.state.traceUuid || '<no trace>'}\n` +
              `New trace: ${traceUuid}`),
    ),
    buttons: [
      {
        text: 'Continue',
        id: 'trace_id_open',  // Used by tests.
        primary: true,
        action: () => {
          hasOpenedNewTrace = true;
          globals.dispatch(Actions.openTraceFromBuffer(maybeTrace));
        },
      },
      {text: 'Cancel'},
    ],
  });

  if (!hasOpenedNewTrace) {
    // We handle this after the modal await rather than in the cancel button
    // action so this has effect even if the user clicks Esc or clicks outside
    // of the modal dialog and dismisses it.
    navigateToOldTraceUuid();
  }
}

function loadTraceFromUrl(url: string) {
  const isLocalhostTraceUrl =
      ['127.0.0.1', 'localhost'].includes((new URL(url)).hostname);

  if (isLocalhostTraceUrl) {
    // This handles the special case of tools/record_android_trace serving the
    // traces from a local webserver and killing it immediately after having
    // seen the HTTP GET request. In those cases store the trace as a file, so
    // when users click on share we don't fail the re-fetch().
    const fileName = url.split('/').pop() || 'local_trace.pftrace';
    const request = fetch(url)
      .then((response) => response.blob())
      .then((blob) => {
        globals.dispatch(Actions.openTraceFromFile({
          file: new File([blob], fileName),
        }));
      })
      .catch((e) => alert(`Could not load local trace ${e}`));
    taskTracker.trackPromise(request, 'Downloading local trace');
  } else {
    globals.dispatch(Actions.openTraceFromUrl({url}));
  }
}

function openTraceFromAndroidBugTool() {
  // TODO(hjd): Unify updateStatus and TaskTracker
  globals.dispatch(Actions.updateStatus(
    {msg: 'Loading trace from ABT extension', timestamp: Date.now() / 1000}));
  const loadInfo = loadAndroidBugToolInfo();
  taskTracker.trackPromise(loadInfo, 'Loading trace from ABT extension');
  loadInfo
    .then((info) => {
      globals.dispatch(Actions.openTraceFromFile({
        file: info.file,
      }));
    })
    .catch((e) => {
      console.error(e);
    });
}
