// 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 {loadPermalink} from './permalink';
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.
    loadPermalink(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);
    });
}
