// Copyright (c) 2019, 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';
import 'dart:io';

import 'package:build_daemon/data/build_status.dart' as daemon;
import 'package:dwds/data/build_result.dart';
import 'package:dwds/dwds.dart';
import 'package:dwds/sdk_configuration.dart';
import 'package:file/local.dart';
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart';
import 'package:http_multi_server/http_multi_server.dart';
import 'package:logging/logging.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf_proxy/shelf_proxy.dart';

import '../command/configuration.dart';
import '../util.dart';
import 'chrome.dart';
import 'handlers/favicon_handler.dart';
import 'utils.dart' show findPackageConfigFilePath, findPackageConfigUri;

Logger _logger = Logger('WebDevServer');

const reloadedSourcesFileName = 'reloaded_sources.json';
const jsLibraryBundleExtension = '.ddc.js';
const multiRootScheme = 'org-dartlang-app';

class ServerOptions {
  final Configuration configuration;
  final int port;
  final String target;
  final int daemonPort;

  ServerOptions(this.configuration, this.port, this.target, this.daemonPort);
}

class WebDevServer {
  final HttpServer _server;
  final http.Client _client;
  final String _protocol;

  final Stream<BuildResult> buildResults;

  /// Can be null if client.js injection is disabled.
  final Dwds? dwds;

  final ExpressionCompilerService? ddcService;

  final String target;

  WebDevServer._(
    this.target,
    this._server,
    this._client,
    this._protocol,
    this.buildResults,
    bool autoRun, {
    this.dwds,
    this.ddcService,
  }) {
    if (autoRun) {
      dwds?.connectedApps.listen((connection) {
        connection.runMain();
      });
    }
  }

  String get host => _server.address.host;
  int get port => _server.port;
  String get protocol => _protocol;

  Future<void> stop() async {
    await dwds?.stop();
    await ddcService?.stop();
    await _server.close(force: true);
    _client.close();
  }

  static Future<WebDevServer> start(
    ServerOptions options,
    Stream<daemon.BuildResults> buildResults,
  ) async {
    final basePath = 'http://localhost:${options.port}';
    var pipeline = const Pipeline();

    if (options.configuration.logRequests) {
      pipeline = pipeline.addMiddleware(logRequests());
    }

    pipeline = pipeline.addMiddleware(interceptFavicon);

    /// JSON-ifiable list of sources that were reloaded in this restart and
    /// follows the following format:
    ///
    /// `src`: A string that corresponds to the file path containing a DDC library
    /// bundle. To support embedded libraries, the path should include the
    /// `baseUri` of the web server.
    /// `module`: The name of the library bundle in `src`.
    /// `libraries`: An array of strings containing the libraries that were
    /// compiled in `src`.
    ///
    /// For example:
    /// ```json
    /// [
    ///   {
    ///     "src": "<baseUri>/<file_name>",
    ///     "module": "<module_name>",
    ///     "libraries": ["<lib1>", "<lib2>"],
    ///   },
    /// ]
    /// ```
    ///
    /// The path of the output file should stay consistent across the lifetime of
    /// the app.
    final reloadedSources = <Map<String, dynamic>>[];

    // Only provide relevant build results
    final filteredBuildResults = buildResults.asyncMap<BuildResult>((results) {
      if (options.configuration.canaryFeatures) {
        // Clear reloaded sources for the new build results.
        reloadedSources.clear();
        results.changedAssets?.forEach((uri) {
          if (uri.path.endsWith(jsLibraryBundleExtension)) {
            final reloadedSource = {
              'src': ddcUriToSourceUrl(basePath, options.target, uri),
              'module': ddcUriToLibraryId(uri),
              'libraries': [ddcUriToLibraryId(uri)],
            };
            reloadedSources.add(reloadedSource);
          }
        });
      }
      final result = results.results.firstWhere(
        (result) => result.target == options.target,
      );
      switch (result.status) {
        case daemon.BuildStatus.started:
          return BuildResult(status: BuildStatus.started);
        case daemon.BuildStatus.failed:
          return BuildResult(status: BuildStatus.failed);
        case daemon.BuildStatus.succeeded:
          return BuildResult(status: BuildStatus.succeeded);
        default:
          break;
      }
      throw StateError('Unexpected Daemon build result: $result');
    });

    var cascade = Cascade();
    final client = IOClient(
      HttpClient()
        ..maxConnectionsPerHost = 200
        ..idleTimeout = const Duration(seconds: 30)
        ..connectionTimeout = const Duration(seconds: 30),
    );
    final assetHandler = proxyHandler(
      'http://localhost:${options.daemonPort}/${options.target}/',
      client: client,
    );

    Dwds? dwds;
    ExpressionCompilerService? ddcService;
    if (options.configuration.enableInjectedClient) {
      final assetReader = ProxyServerAssetReader(
        options.daemonPort,
        root: options.target,
      );

      // TODO(https://github.com/flutter/devtools/issues/5350): Figure out how
      // to determine the build settings from the build.
      // Can we save build metadata in build_web_compilers and and read it in
      // the load strategy?
      final buildSettings = BuildSettings(
        appEntrypoint: Uri.parse(
          '$multiRootScheme:///${options.target}/main.dart',
        ),
        canaryFeatures: options.configuration.canaryFeatures,
        isFlutterApp: false,
        experiments: options.configuration.experiments,
      );

      final LoadStrategy loadStrategy;
      if (options.configuration.canaryFeatures) {
        final frontendServerFileSystem = LocalFileSystem();
        final packageUriMapper = await PackageUriMapper.create(
          frontendServerFileSystem,
          findPackageConfigUri()!,
          useDebuggerModuleNames: false,
        );
        loadStrategy = FrontendServerDdcLibraryBundleStrategyProvider(
          options.configuration.reload,
          assetReader,
          packageUriMapper,
          () async => {},
          buildSettings,
          packageConfigPath: findPackageConfigFilePath(),
          reloadedSourcesUri: Uri.parse('$basePath/$reloadedSourcesFileName'),
          injectScriptLoad: false,
        ).strategy;
      } else {
        loadStrategy = BuildRunnerRequireStrategyProvider(
          options.configuration.reload,
          assetReader,
          buildSettings,
          packageConfigPath: findPackageConfigFilePath(),
        ).strategy;
      }

      if (options.configuration.enableExpressionEvaluation) {
        ddcService = ExpressionCompilerService(
          options.configuration.hostname,
          options.port,
          verbose: options.configuration.verbose,
          sdkConfigurationProvider: const DefaultSdkConfigurationProvider(),
        );
      }
      final shouldServeDevTools =
          options.configuration.debug || options.configuration.debugExtension;

      final debugSettings = DebugSettings(
        enableDebugExtension: options.configuration.debugExtension,
        enableDebugging: options.configuration.debug,
        ddsConfiguration: DartDevelopmentServiceConfiguration(
          enable: !options.configuration.disableDds,
          serveDevTools: shouldServeDevTools,
        ),
        expressionCompiler: ddcService,
      );

      final appMetadata = AppMetadata(hostname: options.configuration.hostname);

      final toolConfiguration = ToolConfiguration(
        loadStrategy: loadStrategy,
        debugSettings: debugSettings,
        appMetadata: appMetadata,
      );
      dwds = await Dwds.start(
        toolConfiguration: toolConfiguration,
        assetReader: assetReader,
        buildResults: filteredBuildResults,
        chromeConnection: () async =>
            (await Chrome.connectedInstance).chromeConnection,
      );
      pipeline = pipeline.addMiddleware(dwds.middleware);
      cascade = cascade.add(dwds.handler);
      if (options.configuration.canaryFeatures) {
        // Add a handler to serve reloaded sources.
        cascade = cascade.add((Request request) {
          if (request.url.path == reloadedSourcesFileName) {
            return Response.ok(
              jsonEncode(reloadedSources),
              headers: {'Content-Type': 'application/json'},
            );
          }
          return Response.notFound('');
        });
      }
      cascade = cascade.add(assetHandler);
    } else {
      cascade = cascade.add(assetHandler);
    }

    final hostname = options.configuration.hostname;
    final tlsCertChain = options.configuration.tlsCertChain ?? '';
    final tlsCertKey = options.configuration.tlsCertKey ?? '';

    HttpServer server;
    final protocol = (tlsCertChain.isNotEmpty && tlsCertKey.isNotEmpty)
        ? 'https'
        : 'http';
    if (protocol == 'https') {
      final serverContext = SecurityContext()
        ..useCertificateChain(tlsCertChain)
        ..usePrivateKey(tlsCertKey);
      server = await HttpMultiServer.bindSecure(
        hostname,
        options.port,
        serverContext,
      );
    } else {
      server = await HttpMultiServer.bind(hostname, options.port);
    }

    serveHttpRequests(server, pipeline.addHandler(cascade.handler), (e, s) {
      _logger.warning('Error serving requests', e, s);
    });

    return WebDevServer._(
      options.target,
      server,
      client,
      protocol,
      filteredBuildResults,
      options.configuration.autoRun,
      dwds: dwds,
      ddcService: ddcService,
    );
  }
}

/// Transforms a package:build JS asset id [uri] into a source url compatible
/// with DDC's bootstrapper.
///
/// [basePath] is the path from which JS files as served up to but not
/// including the path.
/// [target] is the path whose files will be served from [basePath].
/// [uri] is the asset id's uri being transformed.
///
/// Example:
/// basePath: http://localhost:8080
/// target: web
///
/// uri: asset:some_package/web/main.ddc.js
/// returns http://localhost:8080/main.ddc.js
///
/// uri: package:some_package/src/sub_dir/file.ddc.js
/// returns http://localhost:8080/some_package/src/sub_dir/file.ddc.js
String ddcUriToSourceUrl(String basePath, String target, Uri uri) {
  String jsPath;
  if (uri.isScheme('asset')) {
    // This indicates that this asset is the 'main' web asset. We directly
    // serve all files under the package's [target] directory.
    var pathParts = uri.pathSegments.skip(1);
    if (pathParts.first == target) {
      pathParts = pathParts.skip(1);
    }
    jsPath = pathParts.join('/');
  } else if (uri.isScheme('package')) {
    jsPath = 'packages/${uri.path}';
  } else {
    jsPath = uri.path;
  }
  return '$basePath/$jsPath';
}

/// Transforms a package:build JS asset id [uri] into a library id compatible
/// with DDC's bootstrapper.
///
/// Example:
/// uri: asset:some_package/web/main.ddc.js
/// returns org-dartlang-app:///web/main.dart
///
/// uri: package:some_package/src/sub_dir/file.ddc.js
/// returns package:some_package/src/sub_dir/file.dart
String ddcUriToLibraryId(Uri uri) {
  final jsPath = uri.isScheme('package')
      ? 'package:${uri.path}'
      : '$multiRootScheme:///${uri.path}';
  final prefix = jsPath.substring(
    0,
    jsPath.length - jsLibraryBundleExtension.length,
  );
  return '$prefix.dart';
}
