// 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.

import 'dart:async';
import 'dart:convert' show HtmlEscape;
import 'dart:io' hide BytesBuilder;
import 'dart:typed_data' show BytesBuilder;

import 'package:package_config/package_config.dart';
import 'package:test_runner/src/configuration.dart';
import 'package:test_runner/src/repository.dart';
import 'package:test_runner/src/utils.dart';

class DispatchingServer {
  final HttpServer server;
  final Map<String, Function> _handlers = {};
  final void Function(HttpRequest request) _notFound;

  DispatchingServer(this.server, Function? onError, this._notFound) {
    server.listen(_dispatchRequest, onError: onError);
  }

  void addHandler(String prefix, void Function(HttpRequest request) handler) {
    _handlers[prefix] = handler;
  }

  void _dispatchRequest(HttpRequest request) {
    // If the request path matches a prefix in _handlers, send it to that
    // handler.  Otherwise, run the notFound handler.
    for (var prefix in _handlers.keys) {
      if (request.uri.path.startsWith(prefix)) {
        _handlers[prefix]!(request);
        return;
      }
    }
    _notFound(request);
  }
}

/// Interface of the HTTP server:
///
/// /echo: This will stream the data received in the request stream back
///        to the client.
/// /root_dart/X: This will serve the corresponding file from the dart
///               directory (i.e. '$DartDirectory/X').
/// /root_build/X: This will serve the corresponding file from the build
///                directory (i.e. '$BuildDirectory/X').
/// /FOO/packages/PAZ/BAR: This will serve files from the packages listed in
///      the package spec .packages.  Supports a package
///      root or custom package spec, and uses $dart_dir/.packages
///      as the default. This will serve file lib/BAR from the package PAZ.
/// /ws: This will upgrade the connection to a WebSocket connection and echo
///      all data back to the client.
///
/// In case a path does not refer to a file but rather to a directory, a
/// directory listing will be displayed.

const prefixBuildDir = 'root_build';
const prefixDartDir = 'root_dart';

/// Runs a set of servers that are initialized specifically for the needs of our
/// test framework, such as dealing with package-root.
class TestingServers {
  static final _cacheExpirationSeconds = 30;
  static final _harmlessRequestPathSuffixes = [
    "/apple-touch-icon.png",
    "/apple-touch-icon-precomposed.png",
    "/favicon.ico",
    "/foo",
    "/bar",
    "/NonExistingFile",
    "IntentionallyMissingFile",
  ];

  final List<HttpServer> _serverList = [];
  final Uri _buildDirectory;
  final Uri _dartDirectory;
  final Uri _packages;
  late PackageConfig _packageConfig;
  final bool useContentSecurityPolicy;
  final Runtime runtime;
  DispatchingServer? _server;

  TestingServers._(this.useContentSecurityPolicy, this._buildDirectory,
      this._dartDirectory, this._packages, this.runtime);

  factory TestingServers(String buildDirectory, bool useContentSecurityPolicy,
      [Runtime runtime = Runtime.none,
      String? dartDirectory,
      String? packages]) {
    var buildDirectoryUri = Uri.base.resolveUri(Uri.directory(buildDirectory));
    var dartDirectoryUri = dartDirectory == null
        ? Repository.uri
        : Uri.base.resolveUri(Uri.directory(dartDirectory));
    var packagesUri = packages == null
        ? dartDirectoryUri.resolve('.dart_tool/package_config.json')
        : Uri.file(packages);
    return TestingServers._(useContentSecurityPolicy, buildDirectoryUri,
        dartDirectoryUri, packagesUri, runtime);
  }

  String get network => _serverList[0].address.address;

  int get port => _serverList[0].port;

  int get crossOriginPort => _serverList[1].port;

  DispatchingServer? get server => _server;

  /// [startServers] will start two Http servers.
  ///
  /// The first server listens on [port] and sets
  ///   "Access-Control-Allow-Origin: *"
  /// The second server listens on [crossOriginPort] and sets
  ///   "Access-Control-Allow-Origin: client:port1
  ///   "Access-Control-Allow-Credentials: true"
  Future startServers(String host,
      {int port = 0, int crossOriginPort = 0}) async {
    _packageConfig = await loadPackageConfigUri(_packages);

    _server = await _startHttpServer(host, port: port);
    await _startHttpServer(host,
        port: crossOriginPort, allowedPort: _serverList[0].port);
  }

  /// Gets the command line string to spawn the server.
  String get commandLine {
    var dart = Platform.resolvedExecutable;
    var script = _dartDirectory.resolve('pkg/test_runner/bin/http_server.dart');
    var buildDirectory = _buildDirectory.toFilePath();

    return [
      dart,
      script.toFilePath(),
      '-p',
      port,
      '-c',
      crossOriginPort,
      '--network',
      network,
      '--build-directory=$buildDirectory',
      '--runtime=${runtime.name}',
      if (useContentSecurityPolicy) '--csp',
      '--packages=${_packages.toFilePath()}'
    ].join(' ');
  }

  void stopServers() {
    for (var server in _serverList) {
      server.close();
    }
  }

  void _onError(e) {
    DebugLogger.error('HttpServer: an error occurred', e);
  }

  Future<DispatchingServer> _startHttpServer(String host,
      {int port = 0, int allowedPort = -1}) {
    return HttpServer.bind(host, port).then((HttpServer httpServer) {
      var server = DispatchingServer(httpServer, _onError, _sendNotFound);
      server.addHandler('/echo', _handleEchoRequest);
      server.addHandler('/ws', _handleWebSocketRequest);
      fileHandler(HttpRequest request) {
        _handleFileOrDirectoryRequest(request, allowedPort);
      }

      server.addHandler('/$prefixBuildDir', fileHandler);
      server.addHandler('/$prefixDartDir', fileHandler);
      server.addHandler('/packages', fileHandler);
      server.addHandler('/upload', _handleUploadRequest);
      _serverList.add(httpServer);
      return server;
    });
  }

  Future _handleFileOrDirectoryRequest(
      HttpRequest request, int allowedPort) async {
    // Enable browsers to cache file/directory responses.
    var response = request.response;
    response.headers.set("Cache-Control", "max-age=$_cacheExpirationSeconds");
    try {
      var path = _getFileUriFromRequestUri(request.uri);
      if (path != null) {
        var file = File.fromUri(path);
        var directory = Directory.fromUri(path);
        if (await file.exists()) {
          _sendFileContent(request, response, allowedPort, file);
        } else if (await directory.exists()) {
          _sendDirectoryListing(
              await _listDirectory(directory), request, response);
        } else {
          _sendNotFound(request);
        }
      } else {
        if (request.uri.path == '/') {
          var entries = [
            _Entry('root_dart', 'root_dart/'),
            _Entry('root_build', 'root_build/'),
            _Entry('echo', 'echo')
          ];
          _sendDirectoryListing(entries, request, response);
        } else {
          _sendNotFound(request);
        }
      }
    } catch (e) {
      _sendNotFound(request);
    }
  }

  void _handleEchoRequest(HttpRequest request) {
    request.response.headers.set("Access-Control-Allow-Origin", "*");
    request.cast<List<int>>().pipe(request.response).catchError((e) {
      DebugLogger.warning(
          'HttpServer: error while closing the response stream', e);
    });
  }

  void _handleWebSocketRequest(HttpRequest request) {
    WebSocketTransformer.upgrade(request).then((websocket) {
      // We ignore failures to write to the socket, this happens if the browser
      // closes the connection.
      websocket.done.catchError((_) {});
      websocket.listen((data) {
        websocket.add(data);
        if (data == 'close-with-error') {
          // Note: according to the web-sockets spec, a reason longer than 123
          // bytes will produce a SyntaxError on the client.
          websocket.close(WebSocketStatus.unsupportedData, 'X' * 124);
        } else {
          websocket.close();
        }
      }, onError: (e) {
        DebugLogger.warning('HttpServer: error while echoing to WebSocket', e);
      });
    }).catchError((e) {
      DebugLogger.warning(
          'HttpServer: error while transforming to WebSocket', e);
    });
  }

  void _handleUploadRequest(HttpRequest request) async {
    try {
      var builder = await request.fold(BytesBuilder(), (dynamic b, var d) {
        b.add(d);
        return b;
      });
      var data = builder.takeBytes();
      DebugLogger.info(
          'Uploaded data: ${String.fromCharCodes(data as Iterable<int>)}');
      request.response.headers.set("Access-Control-Allow-Origin", "*");
      request.response.close();
    } catch (e) {
      DebugLogger.warning(
          'HttpServer: error while processing upload request', e);
    }
  }

  Uri? _getFileUriFromRequestUri(Uri request) {
    // Go to the top of the file to see an explanation of the URL path scheme.
    var pathSegments = request.normalizePath().pathSegments;
    if (pathSegments.isEmpty) return null;
    var packagesIndex = pathSegments.indexOf('packages');
    if (packagesIndex != -1) {
      var packageUri = Uri(
          scheme: 'package',
          pathSegments: pathSegments.skip(packagesIndex + 1));
      return _packageConfig.resolve(packageUri);
    }
    if (pathSegments[0] == prefixBuildDir) {
      return _buildDirectory.resolve(pathSegments.skip(1).join('/'));
    }
    if (pathSegments[0] == prefixDartDir) {
      return _dartDirectory.resolve(pathSegments.skip(1).join('/'));
    }
    return null;
  }

  Future<List<_Entry>> _listDirectory(Directory directory) {
    var completer = Completer<List<_Entry>>();
    var entries = <_Entry>[];

    directory.list().listen((FileSystemEntity fse) {
      var segments = fse.uri.pathSegments;
      if (fse is File) {
        var filename = segments.last;
        entries.add(_Entry(filename, filename));
      } else if (fse is Directory) {
        var dirname = segments[segments.length - 2];
        entries.add(_Entry(dirname, '$dirname/'));
      }
    }, onDone: () {
      completer.complete(entries);
    });
    return completer.future;
  }

  void _sendDirectoryListing(
      List<_Entry> entries, HttpRequest request, HttpResponse response) {
    response.headers.set('Content-Type', 'text/html');
    var header = '''<!DOCTYPE html>
    <html>
    <head>
      <title>${request.uri.path}</title>
      <meta charset="utf-8">
    </head>
    <body>
      <code>
        <div>${request.uri.path}</div>
        <hr/>
        <ul>''';
    var footer = '''
        </ul>
      </code>
    </body>
    </html>''';

    entries.sort();
    response.write(header);
    for (var entry in entries) {
      response.write('<li><a href="${request.uri}/${entry.name}">'
          '${entry.displayName}</a></li>');
    }
    response.write(footer);
    response.close();
    response.done.catchError((e) {
      DebugLogger.warning(
          'HttpServer: error while closing the response stream', e);
    });
  }

  void _sendFileContent(
      HttpRequest request, HttpResponse response, int allowedPort, File file) {
    if (allowedPort != -1) {
      var headerOrigin = request.headers.value('Origin');
      String allowedOrigin;
      if (headerOrigin != null) {
        var origin = Uri.parse(headerOrigin);
        // Allow loading from http://*:$allowedPort in browsers.
        allowedOrigin = '${origin.scheme}://${origin.host}:$allowedPort';
      } else {
        // IE10 appears to be bugged and is not sending the Origin header
        // when making CORS requests to the same domain but different port.
        allowedOrigin = '*';
      }

      response.headers.set("Access-Control-Allow-Origin", allowedOrigin);
      response.headers.set('Access-Control-Allow-Credentials', 'true');
    } else {
      // No allowedPort specified. Allow from anywhere (but cross-origin
      // requests *with credentials* will fail because you can't use "*").
      response.headers.set("Access-Control-Allow-Origin", "*");
    }
    if (useContentSecurityPolicy) {
      // Chrome respects the standardized Content-Security-Policy header,
      // whereas Firefox and IE10 use X-Content-Security-Policy. Safari
      // still uses the WebKit- prefixed version.
      var contentHeaderValue = "script-src 'self'; object-src 'self'";
      for (var header in [
        "Content-Security-Policy",
        "X-Content-Security-Policy"
      ]) {
        response.headers.set(header, contentHeaderValue);
      }
      if (runtime == Runtime.safari) {
        response.headers.set("X-WebKit-CSP", contentHeaderValue);
      }
    }
    if (file.path.endsWith('.html')) {
      response.headers.set('Content-Type', 'text/html');
    } else if (file.path.endsWith('.js') || file.path.endsWith('.mjs')) {
      response.headers.set('Content-Type', 'application/javascript');
    } else if (file.path.endsWith('.dart')) {
      response.headers.set('Content-Type', 'application/dart');
    } else if (file.path.endsWith('.css')) {
      response.headers.set('Content-Type', 'text/css');
    } else if (file.path.endsWith('.xml')) {
      response.headers.set('Content-Type', 'text/xml');
    } else if (file.path.endsWith('.wasm')) {
      response.headers.set('Content-Type', 'application/wasm');
    }
    response.headers.removeAll("X-Frame-Options");
    file.openRead().cast<List<int>>().pipe(response).catchError((e) {
      DebugLogger.warning(
          'HttpServer: error while closing the response stream', e);
    });
  }

  void _sendNotFound(HttpRequest request) {
    bool isHarmlessPath(String path) {
      return _harmlessRequestPathSuffixes.any((pattern) {
        return path.contains(pattern);
      });
    }

    if (!isHarmlessPath(request.uri.path)) {
      DebugLogger.warning('HttpServer: could not find file for request path: '
          '"${request.uri.path}"');
    }
    var response = request.response;
    response.statusCode = HttpStatus.notFound;

    // Send a nice HTML page detailing the error message.  Most browsers expect
    // this, for example, Chrome will simply display a blank page if you don't
    // provide any information.  A nice side effect of this is to work around
    // Firefox bug 1016313
    // (https://bugzilla.mozilla.org/show_bug.cgi?id=1016313).
    response.headers.set(HttpHeaders.contentTypeHeader, 'text/html');
    var escapedPath = const HtmlEscape().convert(request.uri.path);
    response.write("""
<!DOCTYPE html>
<html lang='en'>
<head>
<title>Not Found</title>
</head>
<body>
<h1>Not Found</h1>
<p style='white-space:pre'>The file '$escapedPath' could not be found.</p>
</body>
</html>
""");
    response.close();
    response.done.catchError((e) {
      DebugLogger.warning(
          'HttpServer: error while closing the response stream', e);
    });
  }
}

/// Helper class for displaying directory listings.
class _Entry implements Comparable<_Entry> {
  final String name;
  final String displayName;

  _Entry(this.name, this.displayName);

  @override
  int compareTo(_Entry other) {
    return name.compareTo(other.name);
  }
}
