// Copyright (c) 2014, 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:analysis_server/src/channel.dart';
import 'package:analysis_server/src/domain_server.dart';
import 'package:analysis_server/src/protocol.dart';

/**
 * [AnalysisManager] is used to launch and manage an analysis server
 * running in a separate process using either the [start] or [connect] methods.
 */
class AnalysisManager {
  // TODO dynamically allocate port and/or allow client to specify port
  static const int PORT = 3333;

  /**
   * The analysis server process being managed
   * or `null` if managing an analysis server that was already running.
   */
  Process process;

  /**
   * The channel used to communicate with the analysis server.
   */
  ClientCommunicationChannel channel;

  /**
   * Launch analysis server in a separate process
   * and return a future with a manager for that analysis server.
   */
  static Future<AnalysisManager> start(String serverPath) {
    return new AnalysisManager()._launchServer(serverPath);
  }

  /**
   * Open a connection to a running analysis server
   * and return a future with a manager for that analysis server.
   */
  static Future<AnalysisManager> connect(String serverUrl) {
    return new AnalysisManager()._openConnection(serverUrl);
  }

  /**
   * Launch an analysis server and open a connection to that server.
   */
  Future<AnalysisManager> _launchServer(String pathToServer) {
    // TODO dynamically allocate port and/or allow client to specify port
    var serverArgs = [pathToServer, '--port', PORT.toString()];
    return Process.start(Platform.executable, serverArgs)
        .catchError((error) {
          exitCode = 1;
          throw 'Failed to launch analysis server: $error';
        })
        .then(_listenForPort);
  }

  /**
   * Listen for a port from the given analysis server process.
   */
  Future<AnalysisManager> _listenForPort(Process process) {
    this.process = process;

    // Echo stdout and stderr
    Stream out = process.stdout.transform(UTF8.decoder).asBroadcastStream();
    out.listen((line) => print(line));
    process.stderr.pipe(stderr);

    // Listen for port from server
    const String pattern = 'Listening on port ';
    return out.firstWhere((String line) => line.startsWith(pattern))
        .timeout(new Duration(seconds: 10))
        .catchError((error) {
          exitCode = 1;
          process.kill();
          throw 'Expected port from analysis server';
        })
        .then((String line) {
          String port = line.substring(pattern.length).trim();
          var url = 'ws://${InternetAddress.LOOPBACK_IP_V4.address}:$port/';
          return _openConnection(url);
        });
  }

  /**
   * Open a connection to the analysis server using the given URL.
   */
  Future<AnalysisManager> _openConnection(String serverUrl) {
    var onError = (error) {
      exitCode = 1;
      if (process != null) {
        process.kill();
      }
      throw 'Failed to connect to analysis server at $serverUrl\n  $error';
    };
    try {
      return WebSocket.connect(serverUrl)
          .catchError(onError)
          .then((WebSocket socket) {
            this.channel = new WebSocketClientChannel(socket);
            return this;
          });
    } catch (error) {
      onError(error);
    }
  }

  /**
   * Stop the analysis server.
   *
   * Returns `true` if the signal is successfully sent and process terminates.
   * Otherwise there was no attached process or the signal could not be sent,
   * usually meaning that the process is already dead.
   */
  Future<bool> stop() {
    if (process == null) {
      return new Future.value(false);
    }
    var request = new Request('0', ServerDomainHandler.SHUTDOWN_METHOD);
    channel.sendRequest(request);
    return process.exitCode
        .timeout(new Duration(seconds: 10))
        .catchError((error) {
          process.kill();
          throw 'Expected server to shutdown';
        })
        .then((result) {
          if (result != 0) {
            exitCode = result;
          }
          return true;
        });
  }

}
