// 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.

// Keep this import first.
import '../base/disposable_polyfill';
import '../base/static_initializers';
import NON_CORE_PLUGINS from '../gen/all_plugins';
import CORE_PLUGINS from '../gen/all_core_plugins';
import {Draft} from 'immer';
import m from 'mithril';
import {defer} from '../base/deferred';
import {addErrorHandler, reportError} from '../base/logging';
import {Store} from '../base/store';
import {Actions, DeferredAction, StateActions} from '../common/actions';
import {traceEvent} from '../core/metatracing';
import {State} from '../common/state';
import {initController, runControllers} from '../controller';
import {isGetCategoriesResponse} from '../controller/chrome_proxy_record_controller';
import {RECORDING_V2_FLAG, featureFlags} from '../core/feature_flags';
import {initLiveReload} from '../core/live_reload';
import {raf} from '../core/raf_scheduler';
import {initWasm} from '../trace_processor/wasm_engine_proxy';
import {setScheduleFullRedraw} from '../widgets/raf';
import {UiMain} from './ui_main';
import {initCssConstants} from './css_constants';
import {registerDebugGlobals} from './debug';
import {maybeShowErrorDialog} from './error_dialog';
import {ExplorePage} from './explore_page';
import {installFileDropHandler} from './file_drop_handler';
import {FlagsPage} from './flags_page';
import {globals} from './globals';
import {HomePage} from './home_page';
import {InsightsPage} from './insights_page';
import {MetricsPage} from './metrics_page';
import {PluginsPage} from './plugins_page';
import {postMessageHandler} from './post_message_handler';
import {QueryPage} from './query_page';
import {RecordPage, updateAvailableAdbDevices} from './record_page';
import {RecordPageV2} from './record_page_v2';
import {Route, Router} from '../core/router';
import {CheckHttpRpcConnection} from './rpc_http_dialog';
import {TraceInfoPage} from './trace_info_page';
import {maybeOpenTraceFromRoute} from './trace_url_handler';
import {ViewerPage} from './viewer_page';
import {VizPage} from './viz_page';
import {WidgetsPage} from './widgets_page';
import {HttpRpcEngine} from '../trace_processor/http_rpc_engine';
import {showModal} from '../widgets/modal';
import {IdleDetector} from './idle_detector';
import {IdleDetectorWindow} from './idle_detector_interface';
import {pageWithTrace} from './pages';
import {AppImpl} from '../core/app_impl';
import {addSqlTableTab} from './sql_table_tab';
import {getServingRoot} from '../base/http_utils';
import {configureExtensions} from '../public/lib/extensions';
import {
  addDebugCounterTrack,
  addDebugSliceTrack,
} from '../public/lib/debug_tracks/debug_tracks';
import {addVisualizedArgTracks} from './visualized_args_tracks';
import {addQueryResultsTab} from '../public/lib/query_table/query_result_tab';

const EXTENSION_ID = 'lfmkphfpdbjijhpomgecfikhfohaoine';

const CSP_WS_PERMISSIVE_PORT = featureFlags.register({
  id: 'cspAllowAnyWebsocketPort',
  name: 'Relax Content Security Policy for 127.0.0.1:*',
  description:
    'Allows simultaneous usage of several trace_processor_shell ' +
    '-D --http-port 1234 by opening ' +
    'https://ui.perfetto.dev/#!/?rpc_port=1234',
  defaultValue: false,
});

function setExtensionAvailability(available: boolean) {
  globals.dispatch(
    Actions.setExtensionAvailable({
      available,
    }),
  );
}

function routeChange(route: Route) {
  raf.scheduleFullRedraw();
  maybeOpenTraceFromRoute(route);
  if (route.fragment) {
    // This needs to happen after the next redraw call. It's not enough
    // to use setTimeout(..., 0); since that may occur before the
    // redraw scheduled above.
    raf.addPendingCallback(() => {
      const e = document.getElementById(route.fragment);
      if (e) {
        e.scrollIntoView();
      }
    });
  }
}

function setupContentSecurityPolicy() {
  // Note: self and sha-xxx must be quoted, urls data: and blob: must not.

  let rpcPolicy = [
    'http://127.0.0.1:9001', // For trace_processor_shell --httpd.
    'ws://127.0.0.1:9001', // Ditto, for the websocket RPC.
  ];
  if (CSP_WS_PERMISSIVE_PORT.get()) {
    const route = Router.parseUrl(window.location.href);
    if (/^\d+$/.exec(route.args.rpc_port ?? '')) {
      rpcPolicy = [
        `http://127.0.0.1:${route.args.rpc_port}`,
        `ws://127.0.0.1:${route.args.rpc_port}`,
      ];
    }
  }
  const policy = {
    'default-src': [
      `'self'`,
      // Google Tag Manager bootstrap.
      `'sha256-LirUKeorCU4uRNtNzr8tlB11uy8rzrdmqHCX38JSwHY='`,
    ],
    'script-src': [
      `'self'`,
      // TODO(b/201596551): this is required for Wasm after crrev.com/c/3179051
      // and should be replaced with 'wasm-unsafe-eval'.
      `'unsafe-eval'`,
      'https://*.google.com',
      'https://*.googleusercontent.com',
      'https://www.googletagmanager.com',
      'https://*.google-analytics.com',
    ],
    'object-src': ['none'],
    'connect-src': [
      `'self'`,
      'ws://127.0.0.1:8037', // For the adb websocket server.
      'https://*.google-analytics.com',
      'https://*.googleapis.com', // For Google Cloud Storage fetches.
      'blob:',
      'data:',
    ].concat(rpcPolicy),
    'img-src': [
      `'self'`,
      'data:',
      'blob:',
      'https://*.google-analytics.com',
      'https://www.googletagmanager.com',
      'https://*.googleapis.com',
    ],
    'style-src': [`'self'`, `'unsafe-inline'`],
    'navigate-to': ['https://*.perfetto.dev', 'self'],
  };
  const meta = document.createElement('meta');
  meta.httpEquiv = 'Content-Security-Policy';
  let policyStr = '';
  for (const [key, list] of Object.entries(policy)) {
    policyStr += `${key} ${list.join(' ')}; `;
  }
  meta.content = policyStr;
  document.head.appendChild(meta);
}

function setupExtentionPort(extensionLocalChannel: MessageChannel) {
  // We proxy messages between the extension and the controller because the
  // controller's worker can't access chrome.runtime.
  const extensionPort =
    // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
    window.chrome && chrome.runtime
      ? chrome.runtime.connect(EXTENSION_ID)
      : undefined;

  setExtensionAvailability(extensionPort !== undefined);

  if (extensionPort) {
    // Send messages to keep-alive the extension port.
    const interval = setInterval(() => {
      extensionPort.postMessage({
        method: 'ExtensionVersion',
      });
    }, 25000);
    extensionPort.onDisconnect.addListener((_) => {
      setExtensionAvailability(false);
      clearInterval(interval);
      void chrome.runtime.lastError; // Needed to not receive an error log.
    });
    // This forwards the messages from the extension to the controller.
    extensionPort.onMessage.addListener(
      (message: object, _port: chrome.runtime.Port) => {
        if (isGetCategoriesResponse(message)) {
          globals.dispatch(Actions.setChromeCategories(message));
          return;
        }
        extensionLocalChannel.port2.postMessage(message);
      },
    );
  }

  // This forwards the messages from the controller to the extension
  extensionLocalChannel.port2.onmessage = ({data}) => {
    if (extensionPort) extensionPort.postMessage(data);
  };
}

function main() {
  // Setup content security policy before anything else.
  setupContentSecurityPolicy();

  AppImpl.initialize({
    rootUrl: getServingRoot(),
    initialRouteArgs: Router.parseUrl(window.location.href).args,
    clearState: () => globals.dispatch(Actions.clearState({})),
  });

  // Wire up raf for widgets.
  setScheduleFullRedraw(() => raf.scheduleFullRedraw());

  // Load the css. The load is asynchronous and the CSS is not ready by the time
  // appendChild returns.
  const cssLoadPromise = defer<void>();
  const css = document.createElement('link');
  css.rel = 'stylesheet';
  css.href = globals.root + 'perfetto.css';
  css.onload = () => cssLoadPromise.resolve();
  css.onerror = (err) => cssLoadPromise.reject(err);
  const favicon = document.head.querySelector('#favicon');
  if (favicon instanceof HTMLLinkElement) {
    favicon.href = globals.root + 'assets/favicon.png';
  }

  // Load the script to detect if this is a Googler (see comments on globals.ts)
  // and initialize GA after that (or after a timeout if something goes wrong).
  function initAnalyticsOnScriptLoad() {
    AppImpl.instance.analytics.initialize(globals.isInternalUser);
  }
  const script = document.createElement('script');
  script.src =
    'https://storage.cloud.google.com/perfetto-ui-internal/is_internal_user.js';
  script.async = true;
  script.onerror = () => initAnalyticsOnScriptLoad();
  script.onload = () => initAnalyticsOnScriptLoad();
  setTimeout(() => initAnalyticsOnScriptLoad(), 5000);

  document.head.append(script, css);

  // Route errors to both the UI bugreport dialog and Analytics (if enabled).
  addErrorHandler(maybeShowErrorDialog);
  addErrorHandler((e) => AppImpl.instance.analytics.logError(e));

  // Add Error handlers for JS error and for uncaught exceptions in promises.
  window.addEventListener('error', (e) => reportError(e));
  window.addEventListener('unhandledrejection', (e) => reportError(e));

  const extensionLocalChannel = new MessageChannel();

  initWasm(globals.root);
  initController(extensionLocalChannel.port1);

  // These need to be set before globals.initialize.
  globals.initialize(stateActionDispatcher);

  globals.serviceWorkerController.install();

  globals.store.subscribe(scheduleRafAndRunControllersOnStateChange);
  globals.publishRedraw = () => raf.scheduleFullRedraw();

  setupExtentionPort(extensionLocalChannel);

  // Put debug variables in the global scope for better debugging.
  registerDebugGlobals();

  // Prevent pinch zoom.
  document.body.addEventListener(
    'wheel',
    (e: MouseEvent) => {
      if (e.ctrlKey) e.preventDefault();
    },
    {passive: false},
  );

  cssLoadPromise.then(() => onCssLoaded());

  if (AppImpl.instance.testingMode) {
    document.body.classList.add('testing');
  }

  (window as {} as IdleDetectorWindow).waitForPerfettoIdle = (ms?: number) => {
    return new IdleDetector().waitForPerfettoIdle(ms);
  };
}

function onCssLoaded() {
  initCssConstants();
  // Clear all the contents of the initial page (e.g. the <pre> error message)
  // And replace it with the root <main> element which will be used by mithril.
  document.body.innerHTML = '';

  const router = new Router({
    '/': HomePage,
    '/explore': pageWithTrace(ExplorePage),
    '/flags': FlagsPage,
    '/info': pageWithTrace(TraceInfoPage),
    '/insights': pageWithTrace(InsightsPage),
    '/metrics': pageWithTrace(MetricsPage),
    '/plugins': PluginsPage,
    '/query': pageWithTrace(QueryPage),
    '/record': RECORDING_V2_FLAG.get() ? RecordPageV2 : RecordPage,
    '/viewer': pageWithTrace(ViewerPage),
    '/viz': pageWithTrace(VizPage),
    '/widgets': WidgetsPage,
  });
  router.onRouteChanged = routeChange;

  raf.domRedraw = () => {
    m.render(document.body, m(UiMain, router.resolve()));
  };

  if (
    (location.origin.startsWith('http://localhost:') ||
      location.origin.startsWith('http://127.0.0.1:')) &&
    !AppImpl.instance.embeddedMode &&
    !AppImpl.instance.testingMode
  ) {
    initLiveReload();
  }

  if (!RECORDING_V2_FLAG.get()) {
    updateAvailableAdbDevices();
    try {
      navigator.usb.addEventListener('connect', () =>
        updateAvailableAdbDevices(),
      );
      navigator.usb.addEventListener('disconnect', () =>
        updateAvailableAdbDevices(),
      );
    } catch (e) {
      console.error('WebUSB API not supported');
    }
  }

  // Will update the chip on the sidebar footer that notifies that the RPC is
  // connected. Has no effect on the controller (which will repeat this check
  // before creating a new engine).
  // Don't auto-open any trace URLs until we get a response here because we may
  // accidentially clober the state of an open trace processor instance
  // otherwise.
  maybeChangeRpcPortFromFragment();
  CheckHttpRpcConnection().then(() => {
    const route = Router.parseUrl(window.location.href);
    if (!AppImpl.instance.embeddedMode) {
      installFileDropHandler();
    }

    // Don't allow postMessage or opening trace from route when the user says
    // that they want to reuse the already loaded trace in trace processor.
    const traceSource = AppImpl.instance.trace?.traceInfo.source;
    if (traceSource && traceSource.type === 'HTTP_RPC') {
      return;
    }

    // Add support for opening traces from postMessage().
    window.addEventListener('message', postMessageHandler, {passive: true});

    // Handles the initial ?local_cache_key=123 or ?s=permalink or ?url=...
    // cases.
    routeChange(route);
  });

  // Force one initial render to get everything in place
  m.render(document.body, m(UiMain, router.resolve()));

  // Initialize plugins, now that we are ready to go.
  const pluginManager = AppImpl.instance.plugins;
  CORE_PLUGINS.forEach((p) => pluginManager.registerPlugin(p));
  NON_CORE_PLUGINS.forEach((p) => pluginManager.registerPlugin(p));
  const route = Router.parseUrl(window.location.href);
  const overrides = (route.args.enablePlugins ?? '').split(',');
  pluginManager.activatePlugins(overrides);
}

// If the URL is /#!?rpc_port=1234, change the default RPC port.
// For security reasons, this requires toggling a flag. Detect this and tell the
// user what to do in this case.
function maybeChangeRpcPortFromFragment() {
  const route = Router.parseUrl(window.location.href);
  if (route.args.rpc_port !== undefined) {
    if (!CSP_WS_PERMISSIVE_PORT.get()) {
      showModal({
        title: 'Using a different port requires a flag change',
        content: m(
          'div',
          m(
            'span',
            'For security reasons before connecting to a non-standard ' +
              'TraceProcessor port you need to manually enable the flag to ' +
              'relax the Content Security Policy and restart the UI.',
          ),
        ),
        buttons: [
          {
            text: 'Take me to the flags page',
            primary: true,
            action: () => Router.navigate('#!/flags/cspAllowAnyWebsocketPort'),
          },
        ],
      });
    } else {
      HttpRpcEngine.rpcPort = route.args.rpc_port;
    }
  }
}

function stateActionDispatcher(actions: DeferredAction[]) {
  const edits = actions.map((action) => {
    return traceEvent(`action.${action.type}`, () => {
      return (draft: Draft<State>) => {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        (StateActions as any)[action.type](draft, action.args);
      };
    });
  });
  globals.store.edit(edits);
}

function scheduleRafAndRunControllersOnStateChange(
  store: Store<State>,
  oldState: State,
) {
  // Only redraw if something actually changed
  if (oldState !== store.state) {
    raf.scheduleFullRedraw();
  }
  // Run in a separate task to avoid avoid reentry.
  setTimeout(runControllers, 0);
}

// TODO(primiano): this injection is to break a cirular dependency. See
// comment in sql_table_tab_interface.ts. Remove once we add an extension
// point for context menus.
configureExtensions({
  addDebugCounterTrack,
  addDebugSliceTrack,
  addVisualizedArgTracks,
  addSqlTableTab,
  addQueryResultsTab,
});

main();
