// Copyright (c) 2014, 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.

library pub.barback.web_socket_api;

import 'dart:async';
import 'dart:io';

import 'package:path/path.dart' as path;
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;

import '../utils.dart';
import 'asset_environment.dart';

/// Implements the [WebSocket] API for communicating with a running pub serve
/// process, mainly for use by the Editor.
///
/// This is a [JSON-RPC 2.0](http://www.jsonrpc.org/specification) server. Its
/// methods are described in the method-level documentation below.
class WebSocketApi {
  final WebSocket _socket;
  final AssetEnvironment _environment;
  final _server = new json_rpc.Server();

  WebSocketApi(this._socket, this._environment) {
    _server.registerMethod("urlToAssetId", _urlToAssetId);
    _server.registerMethod("pathToUrls", _pathToUrls);
    _server.registerMethod("serveDirectory", _serveDirectory);
    _server.registerMethod("unserveDirectory", _unserveDirectory);
  }

  /// Listens on the socket.
  ///
  /// Returns a future that completes when the socket has closed. It will
  /// complete with an error if the socket had an error, otherwise it will
  /// complete to `null`.
  Future listen() {
    return _socket.listen((request) {
      _server.parseRequest(request).then((response) {
        if (response != null) _socket.add(response);
      });
    }, cancelOnError: true).asFuture();
  }

  /// Given a URL to an asset that is served by pub, returns the ID of the
  /// asset that would be accessed by that URL.
  ///
  /// The method name is "urlToAssetId" and it takes a "url" parameter for the
  /// URL being mapped:
  ///
  ///     "params": {
  ///       "url": "http://localhost:8080/index.html"
  ///     }
  ///
  /// If successful, it returns a map containing the asset ID's package and
  /// path:
  ///
  ///     "result": {
  ///       "package": "myapp",
  ///       "path": "web/index.html"
  ///     }
  ///
  /// The "path" key in the result is a URL path that's relative to the root
  /// directory of the package identified by "package". The location of this
  /// package may vary depending on which source it was installed from.
  ///
  /// An optional "line" key may be provided whose value must be an integer. If
  /// given, the result will also include a "line" key that maps the line in
  /// the served final file back to the corresponding source line in the asset
  /// that was used to generate that file.
  ///
  /// Examples (where "myapp" is the root package and pub serve is being run
  /// normally with "web" bound to port 8080 and "test" to 8081):
  ///
  ///     http://localhost:8080/index.html    -> myapp|web/index.html
  ///     http://localhost:8081/sub/main.dart -> myapp|test/sub/main.dart
  ///
  /// If the URL is not a domain being served by pub, this returns an error:
  ///
  ///     http://localhost:1234/index.html    -> NOT_SERVED error
  ///
  /// This does *not* currently support the implicit index.html behavior that
  /// pub serve provides for user-friendliness:
  ///
  ///     http://localhost:1234 -> NOT_SERVED error
  ///
  /// This does *not* currently check to ensure the asset actually exists. It
  /// only maps what the corresponding asset *should* be for that URL.
  Future<Map> _urlToAssetId(json_rpc.Parameters params) {
    var url = params["url"].asUri;

    // If a line number was given, map it to the output line.
    var line = params["line"].asIntOr(null);

    return _environment.getAssetIdForUrl(url).then((id) {
      if (id == null) {
        throw new json_rpc.RpcException(_Error.NOT_SERVED,
            '"${url.host}:${url.port}" is not being served by pub.');
      }

      // TODO(rnystrom): When this is hooked up to actually talk to barback to
      // see if assets exist, consider supporting implicit index.html at that
      // point.

      var result = {"package": id.package, "path": id.path};

      // Map the line.
      // TODO(rnystrom): Right now, source maps are not supported and it just
      // passes through the original line. This lets the editor start using
      // this API before we've fully implemented it. See #12339 and #16061.
      if (line != null) result["line"] = line;

      return result;
    });
  }

  /// Given a path on the filesystem, returns the URLs served by pub that can be
  /// used to access asset found at that path.
  ///
  /// The method name is "pathToUrls" and it takes a "path" key (a native OS
  /// path which may be absolute or relative to the root directory of the
  /// entrypoint package) for the path being mapped:
  ///
  ///     "params": {
  ///       "path": "web/index.html"
  ///     }
  ///
  /// If successful, it returns a map containing the list of URLs that can be
  /// used to access that asset.
  ///
  ///     "result": {
  ///       "urls": ["http://localhost:8080/index.html"]
  ///     }
  ///
  /// The "path" key may refer to a path in another package, either by referring
  /// to its location within the top-level "packages" directory or by referring
  /// to its location on disk. Only the "lib" and "asset" directories are
  /// visible in other packages:
  ///
  ///     "params": {
  ///       "path": "packages/http/http.dart"
  ///     }
  ///
  /// Assets in the "lib" and "asset" directories will usually have one URL for
  /// each server:
  ///
  ///     "result": {
  ///       "urls": [
  ///         "http://localhost:8080/packages/http/http.dart",
  ///         "http://localhost:8081/packages/http/http.dart"
  ///       ]
  ///     }
  ///
  /// An optional "line" key may be provided whose value must be an integer. If
  /// given, the result will also include a "line" key that maps the line in
  /// the source file to the corresponding output line in the resulting asset
  /// served at the URL.
  ///
  /// Examples (where "myapp" is the root package and pub serve is being run
  /// normally with "web" bound to port 8080 and "test" to 8081):
  ///
  ///     web/index.html      -> http://localhost:8080/index.html
  ///     test/sub/main.dart  -> http://localhost:8081/sub/main.dart
  ///
  /// If the asset is not in a directory being served by pub, returns an error:
  ///
  ///     example/index.html  -> NOT_SERVED error
  Future<Map> _pathToUrls(json_rpc.Parameters params) {
    var assetPath = params["path"].asString;
    var line = params["line"].asIntOr(null);

    return _environment.getUrlsForAssetPath(assetPath).then((urls) {
      if (urls.isEmpty) {
        throw new json_rpc.RpcException(_Error.NOT_SERVED,
            'Asset path "$assetPath" is not currently being served.');
      }

      var result = {"urls": urls.map((url) => url.toString()).toList()};

      // Map the line.
      // TODO(rnystrom): Right now, source maps are not supported and it just
      // passes through the original line. This lets the editor start using
      // this API before we've fully implemented it. See #12339 and #16061.
      if (line != null) result["line"] = line;

      return result;
    });
  }

  /// Given a relative directory path within the entrypoint package, binds a
  /// new port to serve from that path and returns its URL.
  ///
  /// The method name is "serveDirectory" and it takes a "path" key (a native
  /// OS path relative to the root of the entrypoint package) for the directory
  /// being served:
  ///
  ///     "params": {
  ///       "path": "example/awesome"
  ///     }
  ///
  /// If successful, it returns a map containing the URL that can be used to
  /// access the directory.
  ///
  ///     "result": {
  ///       "url": "http://localhost:8083"
  ///     }
  ///
  /// If the directory is already being served, returns the previous URL.
  Future<Map> _serveDirectory(json_rpc.Parameters params) {
    var rootDirectory = _validateRelativePath(params, "path");
    return _environment.serveDirectory(rootDirectory).then((server) {
      return {
        "url": server.url.toString()
      };
    }).catchError((error) {
      if (error is! OverlappingSourceDirectoryException) throw error;

      var dir = pluralize("directory", error.overlappingDirectories.length,
          plural: "directories");
      var overlapping = toSentence(error.overlappingDirectories.map(
          (dir) => '"$dir"'));
      print("data: ${error.overlappingDirectories}");
      throw new json_rpc.RpcException(_Error.OVERLAPPING,
          'Path "$rootDirectory" overlaps already served $dir $overlapping.',
          data: {
            "directories": error.overlappingDirectories
          });
    });
  }

  /// Given a relative directory path within the entrypoint package, unbinds
  /// the server previously bound to that directory and returns its (now
  /// unreachable) URL.
  ///
  /// The method name is "unserveDirectory" and it takes a "path" key (a
  /// native OS path relative to the root of the entrypoint package) for the
  /// directory being unserved:
  ///
  ///     "params": {
  ///       "path": "example/awesome"
  ///     }
  ///
  /// If successful, it returns a map containing the URL that used to be used
  /// to access the directory.
  ///
  ///     "result": {
  ///       "url": "http://localhost:8083"
  ///     }
  ///
  /// If no server is bound to that directory, it returns a `NOT_SERVED` error.
  Future<Map> _unserveDirectory(json_rpc.Parameters params) {
    var rootDirectory = _validateRelativePath(params, "path");
    return _environment.unserveDirectory(rootDirectory).then((url) {
      if (url == null) {
        throw new json_rpc.RpcException(_Error.NOT_SERVED,
            'Directory "$rootDirectory" is not bound to a server.');
      }

      return {"url": url.toString()};
    });
  }

  /// Validates that [command] has a field named [key] whose value is a string
  /// containing a relative path that doesn't reach out of the entrypoint
  /// package's root directory.
  ///
  /// Returns the path if found, or throws a [_WebSocketException] if
  /// validation failed.
  String _validateRelativePath(json_rpc.Parameters params, String key) {
    var pathString = params[key].asString;

    if (!path.isRelative(pathString)) {
      throw new json_rpc.RpcException.invalidParams(
          '"$key" must be a relative path. Got "$pathString".');
    }

    if (!path.isWithin(".", pathString)) {
      throw new json_rpc.RpcException.invalidParams(
          '"$key" cannot reach out of its containing directory. '
          'Got "$pathString".');
    }

    return pathString;
  }
}


/// The pub-specific JSON RPC error codes.
class _Error {
  /// The specified directory is not being served.
  static const NOT_SERVED = 1;

  /// The specified directory overlaps one or more ones already being served.
  static const OVERLAPPING = 2;
}
