// Copyright (c) 2024, 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:frontend_server/starter.dart';

const frontEndResponsePrefix = 'result ';
const fakeBoundaryKey = '42';

final debug = false;

/// Represents the output of a FrontendServer's 'compile' or 'recompile'.
class CompilerOutput {
  CompilerOutput({
    required this.outputDillPath,
    required this.errorCount,
    this.sources = const [],
    this.outputText = '',
  });

  /// Output for a 'reject' response.
  factory CompilerOutput.rejectOutput() {
    return CompilerOutput(
      outputDillPath: '',
      errorCount: 0,
    );
  }

  final String outputDillPath;
  final int errorCount;
  final List<Uri> sources;
  final String outputText;
}

enum FrontendServerState {
  awaitingResult,
  awaitingKey,
  collectingResultSources,
  awaitingReject,
  awaitingRejectKey,
  finished,
}

/// Controls and synchronizes the Frontend Server during hot reloaad tests.
///
/// The Frontend Server accepts the following instructions:
///
/// ```
/// > compile <input.dart>
///
/// > recompile [<input.dart>] <boundary-key>
///   <dart file>
///   <dart file>
///   ...
///   <boundary-key>
///
/// > accept
///
/// > quit
///
/// 'compile' and 'recompile' instructions output the following on completion:
///   result <boundary-key>
///   <boundary-key>
///   [<error text or modified files prefixed by '-' or '+'>]
///   <boundary-key> [<output.dill>] <error-count>
/// ```
class HotReloadFrontendServerController {
  final List<String> frontendServerArgs;

  /// Used to send commands to the Frontend Server.
  final StreamController<List<int>> input;

  /// Contains output messages from the Frontend Server.
  final StreamController<List<int>> output;

  /// Contains one event per completed Frontend Server 'compile' or 'recompile'
  /// command.
  final StreamController<CompilerOutput> compileCommandOutputChannel;

  /// An iterator over `compileCommandOutputChannel`.
  /// Should be awaited after every 'compile' or 'recompile' command.
  final StreamIterator<CompilerOutput> synchronizer;

  /// Whether or not this controller has already been started.
  bool started = false;

  /// Initialize to an invalid string prior to the first result.
  String _boundaryKey = 'INVALID';

  late Future<int> frontendServerExitCode;

  /// Source file URIs reported by the Frontend Server.
  List<Uri> sources = [];

  List<String> accumulatedOutput = [];

  int totalErrors = 0;

  FrontendServerState _state = FrontendServerState.awaitingResult;

  HotReloadFrontendServerController._(this.frontendServerArgs, this.input,
      this.output, this.compileCommandOutputChannel, this.synchronizer);

  factory HotReloadFrontendServerController(List<String> frontendServerArgs) {
    var input = StreamController<List<int>>();
    var output = StreamController<List<int>>();
    var compileCommandOutputChannel = StreamController<CompilerOutput>();
    var synchronizer = StreamIterator(compileCommandOutputChannel.stream);
    return HotReloadFrontendServerController._(frontendServerArgs, input,
        output, compileCommandOutputChannel, synchronizer);
  }

  /// Runs the Frontend Server in-memory in incremental mode.
  /// Must be called once before interacting with the Frontend Server.
  void start() {
    if (started) {
      print('Frontend Server has already been started.');
      return;
    }

    output.stream
        .transform(utf8.decoder)
        .transform(const LineSplitter())
        .listen((String s) {
      if (debug) print('Frontend Server Response: $s');
      switch (_state) {
        case FrontendServerState.awaitingReject:
          if (!s.startsWith(frontEndResponsePrefix)) {
            throw Exception('Unexpected Frontend Server response: $s');
          }
          _boundaryKey = s.substring(frontEndResponsePrefix.length);
          _state = FrontendServerState.awaitingRejectKey;
          break;
        case FrontendServerState.awaitingRejectKey:
          if (s != _boundaryKey) {
            throw Exception('Unexpected Frontend Server response for reject '
                '(expected just a key): $s');
          }
          _state = FrontendServerState.finished;
          compileCommandOutputChannel.add(CompilerOutput.rejectOutput());
          _clearState();
          break;
        case FrontendServerState.awaitingResult:
          if (!s.startsWith(frontEndResponsePrefix)) {
            throw Exception('Unexpected Frontend Server response: $s');
          }
          _boundaryKey = s.substring(frontEndResponsePrefix.length);
          _state = FrontendServerState.awaitingKey;
          break;
        case FrontendServerState.awaitingKey:
          // Advance to the next state when we encounter a lone boundary key.
          if (s == _boundaryKey) {
            _state = FrontendServerState.collectingResultSources;
          } else {
            accumulatedOutput.add(s);
          }
        case FrontendServerState.collectingResultSources:
          // Stop and record the result when we encounter a boundary key.
          if (s.startsWith(_boundaryKey)) {
            final compilationReportOutput = s.split(' ');
            final outputDillPath = compilationReportOutput[1];
            final errorCount = int.parse(compilationReportOutput[2]);
            // The FrontendServer accumulates all errors seen so far, so we
            // need to correct for errors from previous compilations.
            final actualErrorCount = errorCount - totalErrors;
            final compilerOutput = CompilerOutput(
              outputDillPath: outputDillPath,
              errorCount: actualErrorCount,
              sources: sources,
              outputText: accumulatedOutput.join('\n'),
            );
            totalErrors = errorCount;
            _state = FrontendServerState.finished;
            compileCommandOutputChannel.add(compilerOutput);
            _clearState();
          } else if (s.startsWith('+')) {
            sources.add(Uri.parse(s.substring(1)));
          } else if (s.startsWith('-')) {
            sources.remove(Uri.parse(s.substring(1)));
          } else {
            throw Exception("Unexpected Frontend Server response "
                "(expected '+' or '-')'): $s");
          }
          break;
        case FrontendServerState.finished:
          throw StateError('Frontend Server reached an unexpected state: $s');
      }
    });

    frontendServerExitCode = starter(
      frontendServerArgs,
      input: input.stream,
      output: IOSink(output.sink),
    );

    started = true;
  }

  /// Clears the controller's state between commands.
  ///
  /// Note: this does not reset the Frontend Server's state.
  void _clearState() {
    sources.clear();
    accumulatedOutput.clear();
    _boundaryKey = 'INVALID';
  }

  Future<CompilerOutput> sendCompile(String dartSourcePath) async {
    if (!started) throw Exception('Frontend Server has not been started yet.');
    _state = FrontendServerState.awaitingResult;
    final command = 'compile $dartSourcePath\n';
    if (debug) print('Sending instruction to Frontend Server:\n$command');
    input.add(command.codeUnits);
    await synchronizer.moveNext();
    return synchronizer.current;
  }

  Future<void> sendCompileAndAccept(String dartSourcePath) async {
    await sendCompile(dartSourcePath);
    sendAccept();
  }

  Future<CompilerOutput> sendRecompile(String entrypointPath,
      {List<String> invalidatedFiles = const [],
      String boundaryKey = fakeBoundaryKey}) async {
    if (!started) throw Exception('Frontend Server has not been started yet.');
    _state = FrontendServerState.awaitingResult;
    final command = 'recompile $entrypointPath $boundaryKey\n'
        '${invalidatedFiles.join('\n')}\n$boundaryKey\n';
    if (debug) print('Sending instruction to Frontend Server:\n$command');
    input.add(command.codeUnits);
    await synchronizer.moveNext();
    return synchronizer.current;
  }

  Future<void> sendRecompileAndAccept(String entrypointPath,
      {List<String> invalidatedFiles = const [],
      String boundaryKey = fakeBoundaryKey}) async {
    await sendRecompile(entrypointPath,
        invalidatedFiles: invalidatedFiles, boundaryKey: boundaryKey);
    sendAccept();
  }

  void sendAccept() {
    if (!started) throw Exception('Frontend Server has not been started yet.');
    final command = 'accept\n';
    if (debug) print('Sending instruction to Frontend Server:\n$command');
    input.add(command.codeUnits);
  }

  Future<void> sendReject() async {
    if (!started) throw Exception('Frontend Server has not been started yet.');
    _state = FrontendServerState.awaitingReject;
    final command = 'reject\n';
    if (debug) print('Sending instruction to Frontend Server:\n$command');
    input.add(command.codeUnits);
    await synchronizer.moveNext();
  }

  void _sendQuit() {
    if (!started) throw Exception('Frontend Server has not been started yet.');
    final command = 'quit\n';
    if (debug) print('Sending instruction to Frontend Server:\n$command');
    input.add(command.codeUnits);
  }

  /// Cleanly shuts down the Frontend Server.
  Future<void> stop() async {
    _sendQuit();
    var exitCode = await frontendServerExitCode;
    started = false;
    if (exitCode != 0) {
      print('Frontend Server exited with non-zero code: $exitCode');
      exit(exitCode);
    }
  }
}
