// Copyright 2014 The Flutter Authors. 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:io' as io;

import 'package:flutter_devicelab/framework/browser.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_static/shelf_static.dart';

/// Runs Chrome, opens the given `appUrl`, and returns the result reported by the
/// app.
///
/// The app is served from the `appDirectory`. Typically, the app is built
/// using `flutter build web` and served from `build/web`.
///
/// The launched app is expected to report the result by sending an HTTP POST
/// request to "/test-result" containing result data as plain text body of the
/// request. This function has no opinion about what that string contains.
Future<String> evalTestAppInChrome({
  required String appUrl,
  required String appDirectory,
  int serverPort = 8080,
  int browserDebugPort = 8081,
}) async {
  io.HttpServer? server;
  Chrome? chrome;
  try {
    final Completer<String> resultCompleter = Completer<String>();
    server = await io.HttpServer.bind('localhost', serverPort);
    final Cascade cascade = Cascade()
      .add((Request request) async {
        if (request.requestedUri.path.endsWith('/test-result')) {
          resultCompleter.complete(await request.readAsString());
          return Response.ok('Test results received');
        }
        return Response.notFound('');
      })
      .add(createStaticHandler(appDirectory));
    shelf_io.serveRequests(server, cascade.handler);
    final io.Directory userDataDirectory = io.Directory.systemTemp.createTempSync('flutter_chrome_user_data.');
    chrome = await Chrome.launch(ChromeOptions(
      headless: true,
      debugPort: browserDebugPort,
      url: appUrl,
      userDataDirectory: userDataDirectory.path,
      windowHeight: 500,
      windowWidth: 500,
    ), onError: resultCompleter.completeError);
    return await resultCompleter.future;
  } finally {
    chrome?.stop();
    await server?.close();
  }
}

typedef ServerRequestListener = void Function(Request);

class AppServer {
  AppServer._(this._server, this.chrome, this.onChromeError);

  static Future<AppServer> start({
    required String appUrl,
    required String appDirectory,
    required String cacheControl,
    int serverPort = 8080,
    int browserDebugPort = 8081,
    bool headless = true,
    List<Handler>? additionalRequestHandlers,
  }) async {
    io.HttpServer server;
    Chrome chrome;
    server = await io.HttpServer.bind('localhost', serverPort);
    final Handler staticHandler = createStaticHandler(appDirectory, defaultDocument: 'index.html');
    Cascade cascade = Cascade();
    if (additionalRequestHandlers != null) {
      for (final Handler handler in additionalRequestHandlers) {
        cascade = cascade.add(handler);
      }
    }
    cascade = cascade.add((Request request) async {
      final Response response = await staticHandler(request);
      return response.change(headers: <String, Object>{
        'cache-control': cacheControl,
      });
    });
    shelf_io.serveRequests(server, cascade.handler);
    final io.Directory userDataDirectory = io.Directory.systemTemp.createTempSync('flutter_chrome_user_data.');
    final Completer<String> chromeErrorCompleter = Completer<String>();
    chrome = await Chrome.launch(ChromeOptions(
      headless: headless,
      debugPort: browserDebugPort,
      url: appUrl,
      userDataDirectory: userDataDirectory.path,
    ), onError: chromeErrorCompleter.complete);
    return AppServer._(server, chrome, chromeErrorCompleter.future);
  }

  final Future<String> onChromeError;
  final io.HttpServer _server;
  final Chrome chrome;

  Future<void> stop() async {
    chrome.stop();
    await _server.close();
  }
}
