content: import 'dart:async';
  import 'dart:convert';
  import 'dart:ffi';
  import 'dart:io';
  import 'dart:isolate';
  import 'dart:ui';
  
  import 'package:fl_clash/models/core.dart';
  import 'package:fl_clash/plugins/app.dart';
  import 'package:fl_clash/plugins/tile.dart';
  import 'package:fl_clash/plugins/vpn.dart';
  import 'package:fl_clash/state.dart';
  import 'package:flutter/material.dart';
  import 'package:flutter_riverpod/flutter_riverpod.dart';
  
  import 'application.dart';
  import 'clash/core.dart';
  import 'clash/lib.dart';
  import 'common/common.dart';
  
  Future<void> main() async {
    globalState.isService = false;
    WidgetsFlutterBinding.ensureInitialized();
    FlutterError.onError = (details) {
      commonPrint.log(details.stack.toString());
    };
    final version = await system.version;
    await clashCore.preload();
    await globalState.initApp(version);
    await android?.init();
    await window?.init(version);
    HttpOverrides.global = FlClashHttpOverrides();
    runApp(ProviderScope(
      child: const Application(),
    ));
  }
  
  @pragma('vm:entry-point')
  Future<void> _service(List<String> flags) async {
    globalState.isService = true;
    WidgetsFlutterBinding.ensureInitialized();
    final quickStart = flags.contains("quick");
    final clashLibHandler = ClashLibHandler();
    await globalState.init();
  
    tile?.addListener(
      _TileListenerWithService(
        onStop: () async {
          await app?.tip(appLocalizations.stopVpn);
          clashLibHandler.stopListener();
          await vpn?.stop();
          exit(0);
        },
      ),
    );
  
    vpn?.handleGetStartForegroundParams = () {
      final traffic = clashLibHandler.getTraffic();
      return json.encode({
        "title": clashLibHandler.getCurrentProfileName(),
        "content": "$traffic"
      });
    };
  
    vpn?.addListener(
      _VpnListenerWithService(
        onDnsChanged: (String dns) {
          clashLibHandler.updateDns(dns);
        },
      ),
    );
    if (!quickStart) {
      _handleMainIpc(clashLibHandler);
    } else {
      commonPrint.log("quick start");
      await ClashCore.initGeo();
      app?.tip(appLocalizations.startVpn);
      final homeDirPath = await appPath.homeDirPath;
      final version = await system.version;
      clashLibHandler
          .quickStart(
        InitParams(
          homeDir: homeDirPath,
          version: version,
        ),
        globalState.getUpdateConfigParams(),
        globalState.getCoreState(),
      )
          .then(
        (res) async {
          if (res.isNotEmpty) {
            await vpn?.stop();
            exit(0);
          }
          await vpn?.start(
            clashLibHandler.getAndroidVpnOptions(),
          );
          clashLibHandler.startListener();
        },
      );
    }
  }
  
  _handleMainIpc(ClashLibHandler clashLibHandler) {
    final sendPort = IsolateNameServer.lookupPortByName(mainIsolate);
    if (sendPort == null) {
      return;
    }
    final serviceReceiverPort = ReceivePort();
    serviceReceiverPort.listen((message) async {
      final res = await clashLibHandler.invokeAction(message);
      sendPort.send(res);
    });
    sendPort.send(serviceReceiverPort.sendPort);
    final messageReceiverPort = ReceivePort();
    clashLibHandler.attachMessagePort(
      messageReceiverPort.sendPort.nativePort,
    );
    messageReceiverPort.listen((message) {
      sendPort.send(message);
    });
  }
  
  @immutable
  class _TileListenerWithService with TileListener {
    final Function() _onStop;
  
    const _TileListenerWithService({
      required Function() onStop,
    }) : _onStop = onStop;
  
    @override
    void onStop() {
      _onStop();
    }
  }
  
  @immutable
  class _VpnListenerWithService with VpnListener {
    final Function(String dns) _onDnsChanged;
  
    const _VpnListenerWithService({
      required Function(String dns) onDnsChanged,
    }) : _onDnsChanged = onDnsChanged;
  
    @override
    void onDnsChanged(String dns) {
      super.onDnsChanged(dns);
      _onDnsChanged(dns);
    }
  }
  