// Copyright 2013 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';

import 'package:path/path.dart' as path;
import 'package:test_api/src/backend/runtime.dart';
import 'package:test_core/src/util/io.dart';

import 'browser.dart';
import 'browser_lock.dart';
import 'browser_process.dart';
import 'common.dart';
import 'environment.dart';
import 'firefox_installer.dart';

/// Provides an environment for the desktop Firefox.
class FirefoxEnvironment implements BrowserEnvironment {
  late final BrowserInstallation _installation;

  @override
  Future<Browser> launchBrowserInstance(Uri url, {bool debug = false}) async {
    return Firefox(url, this, debug: debug);
  }

  @override
  Runtime get packageTestRuntime => Runtime.firefox;

  @override
  Future<void> prepare() async {
    _installation = await getOrInstallFirefox(
      browserLock.firefoxLock.version,
      infoLog: isCirrus ? stdout : DevNull(),
    );
  }

  @override
  Future<void> cleanup() async {}

  @override
  final String name = 'Firefox';

  @override
  String get packageTestConfigurationYamlFile => 'dart_test_firefox.yaml';
}

/// Runs desktop Firefox.
///
/// Most of the communication with the browser is expected to happen via HTTP,
/// so this exposes a bare-bones API. The browser starts as soon as the class is
/// constructed, and is killed when [close] is called.
///
/// Any errors starting or running the process are reported through [onExit].
class Firefox extends Browser {
  /// Starts a new instance of Firefox open to the given [url], which may be a
  /// [Uri] or a [String].
  factory Firefox(Uri url, FirefoxEnvironment firefoxEnvironment, {bool debug = false}) {
    final BrowserInstallation installation = firefoxEnvironment._installation;
    final Completer<Uri> remoteDebuggerCompleter = Completer<Uri>.sync();
    return Firefox._(BrowserProcess(() async {
      // Using a profile on opening will prevent popups related to profiles.
      const String profile = '''
user_pref("browser.shell.checkDefaultBrowser", false);
user_pref("dom.disable_open_during_load", false);
user_pref("dom.max_script_run_time", 0);
''';

      final Directory temporaryProfileDirectory = Directory(
          path.join(environment.webUiDartToolDir.path, 'firefox_profile'));

      // A good source of various Firefox Command Line options:
      // https://developer.mozilla.org/en-US/docs/Mozilla/Command_Line_Options#Browser
      //
      if (temporaryProfileDirectory.existsSync()) {
        temporaryProfileDirectory.deleteSync(recursive: true);
      }
      temporaryProfileDirectory.createSync(recursive: true);
      File(path.join(temporaryProfileDirectory.path, 'prefs.js'))
          .writeAsStringSync(profile);

      final bool isMac = Platform.isMacOS;
      final List<String> args = <String>[
        url.toString(),
        '--profile',
        temporaryProfileDirectory.path,
        if (!debug)
          '--headless',
        '-width $kMaxScreenshotWidth',
        '-height $kMaxScreenshotHeight',
        // On Mac Firefox uses the -- option prefix, while elsewhere it uses the - prefix.
        '${isMac ? '-' : ''}-new-window',
        '${isMac ? '-' : ''}-new-instance',
        '--start-debugger-server $kDevtoolsPort',
      ];

      final Process process =
          await Process.start(installation.executable, args);

      remoteDebuggerCompleter.complete(
          getRemoteDebuggerUrl(Uri.parse('http://localhost:$kDevtoolsPort')));

      unawaited(process.exitCode.then((_) {
        temporaryProfileDirectory.deleteSync(recursive: true);
      }));

      return process;
    }), remoteDebuggerCompleter.future);
  }

  Firefox._(this._process, this.remoteDebuggerUrl);

  final BrowserProcess _process;

  @override
  final Future<Uri> remoteDebuggerUrl;

  @override
  Future<void> get onExit => _process.onExit;

  @override
  Future<void> close() => _process.close();
}
