// 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:dwds/data/build_result.dart';
import 'package:dwds/dwds.dart';
import 'package:vm_service/vm_service.dart';
import 'package:vm_service/vm_service_io.dart';

import '../serve/server_manager.dart';
import '../serve/webdev_server.dart';
import 'daemon.dart';
import 'domain.dart';
import 'utilites.dart';

/// A collection of method and events relevant to the running application.
class AppDomain extends Domain {
  bool _isShutdown = false;
  int? _buildProgressEventId;
  var _progressEventId = 0;

  final _appStates = <String, _AppState>{};

  // Mapping from service name to service method.
  final Map<String, String> _registeredMethodsForService = <String, String>{};

  void _handleBuildResult(BuildResult result, String appId) {
    switch (result.status) {
      case BuildStatus.started:
        _buildProgressEventId = _progressEventId++;
        sendEvent('app.progress', {
          'appId': appId,
          'id': '$_buildProgressEventId',
          'message': 'Building...',
        });
        break;
      case BuildStatus.failed:
        sendEvent('app.progress', {
          'appId': appId,
          'id': '$_buildProgressEventId',
          'finished': true,
        });
        break;
      case BuildStatus.succeeded:
        sendEvent('app.progress', {
          'appId': appId,
          'id': '$_buildProgressEventId',
          'finished': true,
        });
        break;
      default:
        break;
    }
  }

  void _initialize(ServerManager serverManager) {
    serverManager.servers.forEach(_handleAppConnections);
  }

  Future<void> _handleAppConnections(WebDevServer server) async {
    final dwds = server.dwds!;

    // The connection is established right before `main()` is called.
    await for (final appConnection in dwds.connectedApps) {
      final appId = appConnection.request.appId;

      // Check if we already have an active app state for this appId
      if (_appStates.containsKey(appId)) {
        // Reuse existing connection, just run main again
        appConnection.runMain();
        continue;
      }

      final debugConnection = await dwds.debugConnection(appConnection);
      final debugUri = debugConnection.ddsUri ?? debugConnection.uri;
      final vmService = await vmServiceConnectUri(debugUri);

      sendEvent('app.start', {
        'appId': appId,
        'directory': Directory.current.path,
        'deviceId': 'chrome',
        'launchMode': 'run'
      });

      // Set up VM service listeners for this appId
      // ignore: cancel_subscriptions
      final stdOutSub = await _setupVmServiceListeners(appId, vmService);

      sendEvent('app.debugPort', {
        'appId': appId,
        'port': debugConnection.port,
        'wsUri': debugConnection.uri,
      });
      // ignore: cancel_subscriptions
      final resultSub =
          server.buildResults.listen((r) => _handleBuildResult(r, appId));

      final appState = _AppState(debugConnection, resultSub, stdOutSub);
      _appStates[appId] = appState;
      sendEvent('app.started', {
        'appId': appId,
      });

      appConnection.runMain();

      // Handle connection termination - send events first, then cleanup
      unawaited(debugConnection.onDone.whenComplete(() {
        sendEvent('app.log', {
          'appId': appId,
          'log': 'Lost connection to device.',
        });
        sendEvent('app.stop', {
          'appId': appId,
        });
        daemon.shutdown();

        // Clean up app resources
        _cleanupAppConnection(appId, appState);
      }));
    }

    // Shutdown could have been triggered while awaiting above.
    if (_isShutdown) dispose();
  }

  void _onServiceEvent(Event e) {
    if (e.kind == EventKind.kServiceRegistered) {
      final serviceName = e.service!;
      _registeredMethodsForService[serviceName] = e.method!;
    }

    if (e.kind == EventKind.kServiceUnregistered) {
      final serviceName = e.service!;
      _registeredMethodsForService.remove(serviceName);
    }
  }

  AppDomain(Daemon daemon, ServerManager serverManager) : super(daemon, 'app') {
    registerHandler('restart', _restart);
    registerHandler('callServiceExtension', _callServiceExtension);
    registerHandler('stop', _stop);

    _initialize(serverManager);
  }

  Future<Map<String, dynamic>?> _callServiceExtension(
      Map<String, dynamic> args) async {
    final appId = getStringArg(args, 'appId', required: true);
    final appState = _appStates[appId];
    if (appState == null) {
      throw ArgumentError.value(appId, 'appId', 'Not found');
    }
    final methodName = getStringArg(args, 'methodName', required: true)!;
    final params = args['params'] != null
        ? (args['params'] as Map<String, dynamic>)
        : <String, dynamic>{};
    final response = await appState.vmService!
        .callServiceExtension(methodName, args: params);
    return response.json;
  }

  Future<Map<String, dynamic>> _restart(Map<String, dynamic> args) async {
    final appId = getStringArg(args, 'appId', required: true);
    final appState = _appStates[appId];
    if (appState == null) {
      throw ArgumentError.value(appId, 'appId', 'Not found');
    }
    final fullRestart = getBoolArg(args, 'fullRestart') ?? false;
    if (!fullRestart) {
      return {
        'code': 1,
        'message': 'hot reload not yet supported by webdev',
      };
    }
    // TODO(grouma) - Support pauseAfterRestart.
    // var pauseAfterRestart = getBoolArg(args, 'pause') ?? false;
    final stopwatch = Stopwatch()..start();
    _progressEventId++;
    sendEvent('app.progress', {
      'appId': appId,
      'id': '$_progressEventId',
      'message': 'Performing hot restart...',
      'progressId': 'hot.restart',
    });
    final restartMethod =
        _registeredMethodsForService['hotRestart'] ?? 'hotRestart';
    final response =
        await appState.vmService!.callServiceExtension(restartMethod);
    sendEvent('app.progress', {
      'appId': appId,
      'id': '$_progressEventId',
      'finished': true,
      'progressId': 'hot.restart',
    });
    sendEvent('app.log', {
      'appId': appId,
      'log': 'Restarted application in ${stopwatch.elapsedMilliseconds}ms'
    });
    return {
      'code': response.type == 'Success' ? 0 : 1,
      'message': response.toString()
    };
  }

  Future<bool> _stop(Map<String, dynamic> args) async {
    final appId = getStringArg(args, 'appId', required: true);
    final appState = _appStates[appId];
    if (appState == null) {
      throw ArgumentError.value(appId, 'appId', 'Not found');
    }
    // Note that this triggers the daemon to shutdown as we listen for the
    // tabConnection to close to initiate a shutdown.
    await appState._debugConnection.close();
    // Wait for the daemon to gracefully shutdown before sending success.
    await daemon.onExit;
    return true;
  }

  /// Sets up VM service listeners for the given appId.
  /// Returns the stdout subscription.
  Future<StreamSubscription<Event>> _setupVmServiceListeners(
      String appId, VmService vmService) async {
    try {
      vmService.onServiceEvent.listen(_onServiceEvent);
      await vmService.streamListen(EventStreams.kService);
    } catch (_) {}

    // ignore: cancel_subscriptions
    final stdoutSubscription = vmService.onStdoutEvent.listen((log) {
      sendEvent('app.log', {
        'appId': appId,
        'log': utf8.decode(base64.decode(log.bytes!)),
      });
    });

    try {
      await vmService.streamListen(EventStreams.kStdout);
    } catch (_) {}

    return stdoutSubscription;
  }

  /// Cleans up an app connection and its associated listeners.
  void _cleanupAppConnection(String appId, _AppState appState) {
    appState.dispose();
    _appStates.remove(appId);
  }

  @override
  void dispose() {
    _isShutdown = true;
    for (final state in _appStates.values) {
      state.dispose();
    }
    _appStates.clear();
  }
}

class _AppState {
  final DebugConnection _debugConnection;
  final StreamSubscription<BuildResult> _resultSub;
  final StreamSubscription<Event> _stdOutSub;

  bool _isDisposed = false;

  VmService? get vmService => _debugConnection.vmService;

  _AppState(this._debugConnection, this._resultSub, this._stdOutSub);

  void dispose() {
    if (_isDisposed) return;
    _isDisposed = true;
    _stdOutSub.cancel();
    _resultSub.cancel();
    _debugConnection.close();
  }
}
