// 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 'package:dwds/data/connect_request.dart';
import 'package:dwds/data/run_request.dart';
import 'package:dwds/data/serializers.dart';
import 'package:dwds/src/handlers/socket_connections.dart';
import 'package:dwds/src/utilities/shared.dart';

/// A connection between the application loaded in the browser and DWDS.
class AppConnection {
  /// The initial connection request sent from the application in the browser.
  final ConnectRequest request;
  final _startedCompleter = Completer<void>();
  final _doneCompleter = Completer<void>();
  final SocketConnection _connection;
  final Future<void> _readyToRunMain;

  AppConnection(this.request, this._connection, this._readyToRunMain) {
    safeUnawaited(_connection.sink.done.then((v) => _doneCompleter.complete()));
  }

  bool get isInKeepAlivePeriod => _connection.isInKeepAlivePeriod;
  void shutDown() => _connection.shutdown();
  bool get isStarted => _startedCompleter.isCompleted;
  Future<void> get onStart => _startedCompleter.future;
  bool get isDone => _doneCompleter.isCompleted;
  Future<void> get onDone => _doneCompleter.future;

  void runMain() {
    if (_startedCompleter.isCompleted) {
      throw StateError('Main has already started.');
    }

    safeUnawaited(_runMain());
  }

  Future<void> _runMain() async {
    await _readyToRunMain;
    _connection.sink.add(jsonEncode(serializers.serialize(RunRequest())));
    _startedCompleter.complete();
  }
}
