// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import {assert} from 'chrome://resources/js/assert.js';


/**
 * The different pages that can be shown at a time.
 * Note: This must remain in sync with the page ids in manager.html!
 */
export enum Page {
  LIST = 'items-list',
  DETAILS = 'details-view',
  ACTIVITY_LOG = 'activity-log',
  SITE_PERMISSIONS = 'site-permissions',
  SITE_PERMISSIONS_ALL_SITES = 'site-permissions-by-site',
  SHORTCUTS = 'keyboard-shortcuts',
  ERRORS = 'error-page',
}

export enum Dialog {
  OPTIONS = 'options',
}

export interface PageState {
  page: Page;
  extensionId?: string;
  subpage?: Dialog;
}

type Listener = (pageState: PageState) => void;

/** @return Whether a and b are equal. */
function isPageStateEqual(a: PageState, b: PageState): boolean {
  return a.page === b.page && a.subpage === b.subpage &&
      a.extensionId === b.extensionId;
}

/**
 * Regular expression that captures the leading slash, the content and the
 * trailing slash in three different groups.
 */
const CANONICAL_PATH_REGEX: RegExp = /(^\/)([\/-\w]+)(\/$)/;

/**
 * A helper object to manage in-page navigations. Since the extensions page
 * needs to support different urls for different subpages (like the details
 * page), we use this object to manage the history and url conversions.
 */
export class NavigationHelper {
  private nextListenerId_: number = 1;
  private listeners_: Map<number, Listener> = new Map();
  private previousPage_?: PageState;

  constructor() {
    this.processRoute_();

    window.addEventListener('popstate', () => {
      this.notifyRouteChanged_(this.getCurrentPage());
    });
  }

  private get currentPath_(): string {
    return location.pathname.replace(CANONICAL_PATH_REGEX, '$1$2');
  }

  /**
   * Going to /configureCommands and /shortcuts should land you on /shortcuts,
   * and going to /sitePermissions should land you on /sitePermissions.
   * These are the only three supported routes, so all other cases will redirect
   * you to root path if not already on it.
   */
  private processRoute_() {
    if (this.currentPath_ === '/configureCommands' ||
        this.currentPath_ === '/shortcuts') {
      window.history.replaceState(
          undefined /* stateObject */, '', '/shortcuts');
    } else if (this.currentPath_ === '/sitePermissions') {
      window.history.replaceState(
          undefined /* stateObject */, '', '/sitePermissions');
    } else if (this.currentPath_ === '/sitePermissions/allSites') {
      window.history.replaceState(
          undefined /* stateObject */, '', '/sitePermissions/allSites');
    } else if (this.currentPath_ !== '/') {
      window.history.replaceState(undefined /* stateObject */, '', '/');
    }
  }

  /**
   * @return The page that should be displayed for the current URL.
   */
  getCurrentPage(): PageState {
    const search = new URLSearchParams(location.search);
    let id = search.get('id');
    if (id) {
      return {page: Page.DETAILS, extensionId: id};
    }
    id = search.get('activity');
    if (id) {
      return {page: Page.ACTIVITY_LOG, extensionId: id};
    }
    id = search.get('options');
    if (id) {
      return {page: Page.DETAILS, extensionId: id, subpage: Dialog.OPTIONS};
    }
    id = search.get('errors');
    if (id) {
      return {page: Page.ERRORS, extensionId: id};
    }

    if (this.currentPath_ === '/shortcuts') {
      return {page: Page.SHORTCUTS};
    }
    if (this.currentPath_ === '/sitePermissions') {
      return {page: Page.SITE_PERMISSIONS};
    }
    if (this.currentPath_ === '/sitePermissions/allSites') {
      return {page: Page.SITE_PERMISSIONS_ALL_SITES};
    }

    return {page: Page.LIST};
  }

  /**
   * Function to add subscribers.
   * @param {!function(!PageState)} listener
   * @return A numerical ID to be used for removing the listener.
   */
  addListener(listener: Listener): number {
    const nextListenerId = this.nextListenerId_++;
    this.listeners_.set(nextListenerId, listener);
    return nextListenerId;
  }

  /**
   * Remove a previously registered listener.
   * @return Whether a listener with the given ID was actually found and
   *   removed.
   */
  removeListener(id: number): boolean {
    return this.listeners_.delete(id);
  }

  /**
   * Function to notify subscribers.
   */
  private notifyRouteChanged_(newPage: PageState) {
    for (const listener of this.listeners_.values()) {
      listener(newPage);
    }
  }

  /**
   * @param newPage the page to navigate to.
   */
  navigateTo(newPage: PageState) {
    const currentPage = this.getCurrentPage();
    if (currentPage && isPageStateEqual(currentPage, newPage)) {
      return;
    }

    this.updateHistory(newPage, false /* replaceState */);
    this.notifyRouteChanged_(newPage);
  }

  /**
   * @param newPage the page to replace the current page with.
   */
  replaceWith(newPage: PageState) {
    this.updateHistory(newPage, true /* replaceState */);
    if (this.previousPage_ && isPageStateEqual(this.previousPage_, newPage)) {
      // Skip the duplicate history entry.
      history.back();
      return;
    }
    this.notifyRouteChanged_(newPage);
  }

  /**
   * Called when a page changes, and pushes state to history to reflect it.
   */
  updateHistory(entry: PageState, replaceState: boolean) {
    let path;
    switch (entry.page) {
      case Page.LIST:
        path = '/';
        break;
      case Page.ACTIVITY_LOG:
        path = '/?activity=' + entry.extensionId;
        break;
      case Page.DETAILS:
        if (entry.subpage) {
          assert(entry.subpage === Dialog.OPTIONS);
          path = '/?options=' + entry.extensionId;
        } else {
          path = '/?id=' + entry.extensionId;
        }
        break;
      case Page.SITE_PERMISSIONS:
        path = '/sitePermissions';
        break;
      case Page.SITE_PERMISSIONS_ALL_SITES:
        path = '/sitePermissions/allSites';
        break;
      case Page.SHORTCUTS:
        path = '/shortcuts';
        break;
      case Page.ERRORS:
        path = '/?errors=' + entry.extensionId;
        break;
    }
    assert(path);
    const state = {url: path};
    const currentPage = this.getCurrentPage();
    const isDialogNavigation = currentPage.page === entry.page &&
        currentPage.extensionId === entry.extensionId;
    // Navigating to a dialog doesn't visually change pages; it just opens
    // a dialog. As such, we replace state rather than pushing a new state
    // on the stack so that hitting the back button doesn't just toggle the
    // dialog.
    if (replaceState || isDialogNavigation) {
      history.replaceState(state, '', path);
    } else {
      this.previousPage_ = currentPage;
      history.pushState(state, '', path);
    }
  }
}

export const navigation = new NavigationHelper();
