// 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.usesDdcLibraryBundle) {
        // 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 {
        if (options.configuration.moduleFormat == 'ddc') {
          loadStrategy = BuildRunnerDdcLibraryBundleStrategyProvider(
            options.configuration.reload,
            assetReader,
            buildSettings,
            packageConfigPath: findPackageConfigFilePath(),
            reloadedSourcesUri: Uri.parse('$basePath/$reloadedSourcesFileName'),
          ).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.usesDdcLibraryBundle) {
        // 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';
}
