// 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 {assertExists, assertTrue} from '../base/logging';
import {
  oneOf,
  optBool,
  optStr,
  record,
  runValidator,
  ValidatedType,
} from '../controller/validators';

import {PageAttrs} from './pages';

export const ROUTE_PREFIX = '#!';
const DEFAULT_ROUTE = '/';

const modes = ['embedded', undefined] as const;
type Mode = typeof modes[number];

// The set of args that can be set on the route via #!/page?a=1&b2.
// Route args are orthogonal to pages (i.e. should NOT make sense only in a
// only within a specific page, use /page/subpages for that).
// Args are !== the querystring (location.search) which is sent to the
// server. The route args are NOT sent to the HTTP server.
// Given this URL:
// http://host/?foo=1&bar=2#!/page/subpage?local_cache_key=a0b1&baz=3.
//
// location.search = 'foo=1&bar=2'.
//   This is seen by the HTTP server. We really don't use querystrings as the
//   perfetto UI is client only.
//
// location.hash = '#!/page/subpage?local_cache_key=a0b1'.
//   This is client-only. All the routing logic in the Perfetto UI uses only
//   this.

const routeArgs = record({
  // The local_cache_key is special and is persisted across navigations.
  local_cache_key: optStr,

  // These are transient and are really set only on startup.

  // Are we loading a trace via ABT.
  openFromAndroidBugTool: optBool,

  // For permalink hash.
  s: optStr,

  // DEPRECATED: for #!/record?p=cpu subpages (b/191255021).
  p: optStr,

  // For fetching traces from Cloud Storage.
  url: optStr,

  // For the 'mode' of the UI. For example when the mode is 'embedded'
  // some features are disabled.
  mode: oneOf<Mode>(modes, undefined),

  // Should we hide the sidebar?
  hideSidebar: optBool,

  // Deep link support
  ts: optStr,
  dur: optStr,
  tid: optStr,
});
type RouteArgs = ValidatedType<typeof routeArgs>;

// A broken down representation of a route.
// For instance: #!/record/gpu?local_cache_key=a0b1
// becomes: {page: '/record', subpage: '/gpu', args: {local_cache_key: 'a0b1'}}
export interface Route {
  page: string;
  subpage: string;
  args: RouteArgs;
}

export interface RoutesMap {
  [key: string]: m.Component<PageAttrs>;
}

// This router does two things:
// 1) Maps fragment paths (#!/page/subpage) to Mithril components.
// The route map is passed to the ctor and is later used when calling the
// resolve() method.
//
// 2) Handles the (optional) args, e.g. #!/page?arg=1&arg2=2.
// Route args are carry information that is orthogonal to the page (e.g. the
// trace id).
// local_cache_key has some special treatment: once a URL has a local_cache_key,
// it gets automatically appended to further navigations that don't have one.
// For instance if the current url is #!/viewer?local_cache_key=1234 and a later
// action (either user-initiated or code-initited) navigates to #!/info, the
// rotuer will automatically replace the history entry with
// #!/info?local_cache_key=1234.
// This is to keep propagating the trace id across page changes, for handling
// tab discards (b/175041881).
//
// This class does NOT deal with the "load a trace when the url contains ?url=
// or ?local_cache_key=". That logic lives in trace_url_handler.ts, which is
// triggered by Router.onRouteChanged().
export class Router {
  private readonly recentChanges: number[] = [];
  private routes: RoutesMap;

  // frontend/index.ts calls maybeOpenTraceFromRoute() + redraw here.
  // This event is decoupled for testing and to avoid circular deps.
  onRouteChanged: (route: Route) => (void) = () => {};

  constructor(routes: RoutesMap) {
    assertExists(routes[DEFAULT_ROUTE]);
    this.routes = routes;
    window.onhashchange = (e: HashChangeEvent) => this.onHashChange(e);
  }

  private onHashChange(e: HashChangeEvent) {
    this.crashIfLivelock();

    const oldRoute = Router.parseUrl(e.oldURL);
    const newRoute = Router.parseUrl(e.newURL);

    if (newRoute.args.local_cache_key === undefined &&
        oldRoute.args.local_cache_key) {
      // Propagate `local_cache_key across` navigations. When a trace is loaded,
      // the URL becomes #!/viewer?local_cache_key=123. `local_cache_key` allows
      // reopening the trace from cache in the case of a reload or discard.
      // When using the UI we can hit "bare" links (e.g. just '#!/info') which
      // don't have the trace_uuid:
      // - When clicking on an <a> element from the sidebar.
      // - When the code calls Router.navigate().
      // - When the user pastes a URL from docs page.
      // In all these cases we want to keep propagating the `local_cache_key`.
      // We do so by re-setting the `local_cache_key` and doing a
      // location.replace which overwrites the history entry (note
      // location.replace is NOT just a String.replace operation).
      newRoute.args.local_cache_key = oldRoute.args.local_cache_key;
    }

    const args = m.buildQueryString(newRoute.args);
    let normalizedFragment = `#!${newRoute.page}${newRoute.subpage}`;
    normalizedFragment += args.length > 0 ? '?' + args : '';
    if (!e.newURL.endsWith(normalizedFragment)) {
      location.replace(normalizedFragment);
      return;
    }

    this.onRouteChanged(newRoute);
  }

  // Returns the component for the current route in the URL.
  // If no route matches the URL, returns a component corresponding to
  // |this.defaultRoute|.
  resolve(): m.Vnode<PageAttrs> {
    const route = Router.parseFragment(location.hash);
    let component = this.routes[route.page];
    if (component === undefined) {
      component = assertExists(this.routes[DEFAULT_ROUTE]);
    }
    return m(component, {subpage: route.subpage} as PageAttrs);
  }

  static navigate(newHash: string) {
    assertTrue(newHash.startsWith(ROUTE_PREFIX));
    window.location.hash = newHash;
  }

  // Breaks down a fragment into a Route object.
  // Sample input:
  // '#!/record/gpu?local_cache_key=abcd-1234'
  // Sample output:
  // {page: '/record', subpage: '/gpu', args: {local_cache_key: 'abcd-1234'}}
  static parseFragment(hash: string): Route {
    const prefixLength = ROUTE_PREFIX.length;
    let route = '';
    if (hash.startsWith(ROUTE_PREFIX)) {
      route = hash.substring(prefixLength).split('?')[0];
    }

    let page = route;
    let subpage = '';
    const splittingPoint = route.indexOf('/', 1);
    if (splittingPoint > 0) {
      page = route.substring(0, splittingPoint);
      subpage = route.substring(splittingPoint);
    }

    const argsStart = hash.indexOf('?');
    const argsStr = argsStart < 0 ? '' : hash.substring(argsStart + 1);
    const rawArgs =
        argsStr ? m.parseQueryString(hash.substring(argsStart)) : {};

    const args = runValidator(routeArgs, rawArgs).result;

    // Javascript sadly distinguishes between foo[bar] === undefined
    // and foo[bar] is not set at all. Here we need the second case to
    // avoid making the URL ugly.
    for (const key of Object.keys(args)) {
      if ((args as any)[key] === undefined) {
        delete (args as any)[key];
      }
    }

    return {page, subpage, args};
  }

  private static parseSearchParams(url: string): RouteArgs {
    const query = (new URL(url)).search;
    const rawArgs = m.parseQueryString(query);
    const args = runValidator(routeArgs, rawArgs).result;

    // Javascript sadly distinguishes between foo[bar] === undefined
    // and foo[bar] is not set at all. Here we need the second case to
    // avoid making the URL ugly.
    for (const key of Object.keys(args)) {
      if ((args as any)[key] === undefined) {
        delete (args as any)[key];
      }
    }

    return args;
  }

  // Like parseFragment() but takes a full URL.
  static parseUrl(url: string): Route {
    const searchArgs = Router.parseSearchParams(url);

    const hashPos = url.indexOf('#');
    const fragment = hashPos < 0 ? '' : url.substring(hashPos);
    const route = Router.parseFragment(fragment);
    route.args = Object.assign({}, searchArgs, route.args);

    return route;
  }

  // Throws if EVENT_LIMIT onhashchange events occur within WINDOW_MS.
  private crashIfLivelock() {
    const WINDOW_MS = 1000;
    const EVENT_LIMIT = 20;
    const now = Date.now();
    while (this.recentChanges.length > 0 &&
           now - this.recentChanges[0] > WINDOW_MS) {
      this.recentChanges.shift();
    }
    this.recentChanges.push(now);
    if (this.recentChanges.length > EVENT_LIMIT) {
      throw new Error('History rewriting livelock');
    }
  }
}
