// 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 * as m from 'mithril';

import {Action, navigate} from '../common/actions';

interface RouteMap {
  [route: string]: m.Component;
}

export const ROUTE_PREFIX = '#!';

export class Router {
  constructor(
      private defaultRoute: string, private routes: RouteMap,
      private dispatch: (a: Action) => void) {
    if (!(defaultRoute in routes)) {
      throw Error('routes must define a component for defaultRoute.');
    }

    window.onhashchange = () => this.navigateToCurrentHash();
  }

  /**
   * Parses and returns the current route string from |window.location.hash|.
   * May return routes that are not defined in |this.routes|.
   */
  getRouteFromHash(): string {
    const prefixLength = ROUTE_PREFIX.length;
    const hash = window.location.hash;

    // Do not try to parse route if prefix doesn't match.
    if (hash.substring(0, prefixLength) !== ROUTE_PREFIX) return '';

    return hash.split('?')[0].substring(prefixLength);
  }

  /**
   * Sets |route| on |window.location.hash|. If |route| if not defined in
   * |this.routes|, dispatches a navigation to |this.defaultRoute|.
   */
  setRouteOnHash(route: string) {
    history.pushState(undefined, undefined, ROUTE_PREFIX + route);

    if (!(route in this.routes)) {
      console.info(
          `Route ${route} not known redirecting to ${this.defaultRoute}.`);
      this.dispatch(navigate(this.defaultRoute));
    }
  }

  /**
   * Dispatches navigation action to |this.getRouteFromHash()| if that is
   * defined in |this.routes|, otherwise to |this.defaultRoute|.
   */
  navigateToCurrentHash() {
    const hashRoute = this.getRouteFromHash();
    const newRoute = hashRoute in this.routes ? hashRoute : this.defaultRoute;
    this.dispatch(navigate(newRoute));
    // TODO(dproy): Handle case when new route has a permalink.
  }

  /**
   * Returns the component for given |route|. If |route| is not defined, returns
   * component of |this.defaultRoute|.
   */
  resolve(route: string|null): m.Component {
    if (!route || !(route in this.routes)) {
      return this.routes[this.defaultRoute];
    }
    return this.routes[route];
  }

  param(key: string) {
    const hash = window.location.hash;
    const paramStart = hash.indexOf('?');
    if (paramStart === -1) return undefined;
    return m.parseQueryString(hash.substring(paramStart))[key];
  }
}
