// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of app;

class LocationManager {
  final ObservatoryApplication _app;

  /// [internalArguments] are parameters specified after a '---' in the
  /// application URL.
  final Map<String, String> internalArguments = new Map<String, String>();

  Uri? _uri;

  /// [uri] is the application uri. Application uris consist of a path and
  /// the queryParameters map.
  Uri get uri => _uri!;

  LocationManager(this._app) {
    window.onPopState.listen(_onBrowserNavigation);
    // Determine initial application path.
    var applicationPath = '${window.location.hash}';
    if ((window.location.hash == '') || (window.location.hash == '#')) {
      // Observatory has loaded but no application path has been specified,
      // use the default.
      // By default we navigate to the VM page.
      applicationPath = Uris.vm();
    }
    // Update current application path.
    window.history
        .replaceState(applicationPath, document.title, applicationPath);
    _updateApplicationLocation(applicationPath);
  }

  bool getBoolParameter(String name, bool defaultValue) {
    var value = uri.queryParameters[name];
    if ("true" == value) return true;
    if ("false" == value) return false;
    return defaultValue;
  }

  /// Called whenever the browser changes the location bar (e.g. forward or
  /// back button press).
  void _onBrowserNavigation(PopStateEvent event) {
    _updateApplicationLocation(window.location.hash);
    _visit();
  }

  /// Given an application url, generate an href link.
  String makeLink(String url) => '#$url';

  /// Update the application location. After this function returns,
  /// [uri] and [debugArguments] will be updated.
  _updateApplicationLocation(String url) {
    if (url == Uris.vmConnect()) {
      // When we go to the vm-connect page, drop all notifications.
      _app.notifications.deleteAll();
    }

    // Chop off leading '#'.
    if (url.startsWith('#')) {
      url = url.substring(1);
    }
    // Fall through handles '#/'
    // Chop off leading '/'.
    if (url.startsWith('/')) {
      url = url.substring(1);
    }
    // Parse out debug arguments.
    if (url.contains('---')) {
      var chunks = url.split('---');
      url = chunks[0];
      if ((chunks.length > 1) && (chunks[1] != '')) {
        internalArguments.clear();
        try {
          internalArguments.addAll(Uri.splitQueryString(chunks[1]));
        } catch (e) {
          Logger.root.warning('Could not parse debug arguments ${e}');
        }
      }
    }
    _uri = Uri.parse(url);
  }

  /// Add [url] to the browser history.
  _addToBrowserHistory(String url) {
    window.history.pushState(url, document.title, url);
  }

  /// Notify the current page that something has changed.
  _visit() {
    Chain.capture(() => _app._visit(_uri!, internalArguments),
        onError: (e, st) {
      if (e is IsolateNotFound) {
        var newPath = ((_app.vm == null || _app.vm.isDisconnected)
            ? '/vm-connect'
            : '/isolate-reconnect');
        var parameters = <String, dynamic>{};
        parameters.addAll(_uri!.queryParameters);
        parameters['originalUri'] = _uri.toString();
        parameters['isolateId'] = parameters['isolateId'];
        var generatedUri = new Uri(path: newPath, queryParameters: parameters);
        go(makeLink(generatedUri.toString()), true);
        return;
      }
      // Surface any uncaught exceptions.
      _app.handleException(e, st);
    });
  }

  /// Navigate to [url].
  void go(String url, [bool addToBrowserHistory = true]) {
    if (addToBrowserHistory) {
      _addToBrowserHistory(url);
    }
    _updateApplicationLocation(url);
    _visit();
  }

  /// Starting with the current uri path and queryParameters, update
  /// queryParameters present in [updateParameters], then generate a new uri
  /// and navigate to that.
  goReplacingParameters(Map updatedParameters,
      [bool addToBrowserHistory = true]) {
    go(makeLinkReplacingParameters(updatedParameters), addToBrowserHistory);
  }

  makeLinkReplacingParameters(Map updatedParameters) {
    var parameters = new Map<String, dynamic>.from(_uri!.queryParameters);
    updatedParameters.forEach((k, v) {
      parameters[k] = v;
    });
    // Ensure path starts with a slash.
    var path = uri.path.startsWith('/') ? uri.path : '/${uri.path}';
    var generatedUri = new Uri(path: path, queryParameters: parameters);
    return makeLink(generatedUri.toString());
  }

  goForwardingParameters(String newPath, [bool addToBrowserHistory = true]) {
    go(makeLinkForwardingParameters(newPath), addToBrowserHistory);
  }

  makeLinkForwardingParameters(String newPath) {
    var parameters = _uri!.queryParameters;
    var generatedUri = new Uri(path: newPath, queryParameters: parameters);
    return makeLink(generatedUri.toString());
  }

  /// Utility event handler when clicking on application url link.
  void onGoto(MouseEvent event) {
    if ((event.button > 0) ||
        event.metaKey ||
        event.ctrlKey ||
        event.shiftKey ||
        event.altKey) {
      // Mouse event is not a left-click OR
      // mouse event is a left-click with a modifier key:
      // let browser handle.
      return;
    }
    event.preventDefault();
    // 'currentTarget' is the dom element that would process the event.
    // If we use 'target' we might get an <em> element or somesuch.
    Element target = event.currentTarget as Element;
    go(target.attributes['href']!);
  }
}
