// Copyright (c) 2016, 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 'dart:math';

import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:test/test.dart';

import '../../test/integration/integration_tests.dart';

void printMemoryResults(String id, String description, List<int> sizes) {
  int minMemory = sizes.fold(sizes.first, min);
  int maxMemory = sizes.fold(sizes.first, max);
  String now = new DateTime.now().toUtc().toIso8601String();
  print('$now ========== $id');
  print('memory: $sizes');
  print('min_memory: $minMemory');
  print('max_memory: $maxMemory');
  print(description.trim());
  print('--------------------');
  print('');
  print('');
}

/**
 * Base class for analysis server memory usage tests.
 */
class AnalysisServerMemoryUsageTest
    extends AbstractAnalysisServerIntegrationTest {
  static const int vmServicePort = 12345;

  int getMemoryUsage() {
    ProcessResult result = _run('curl', <String>[
      'localhost:$vmServicePort/_getAllocationProfile\?isolateId=isolates/root\&gc=full'
    ]);
    Map json = JSON.decode(result.stdout);
    Map heaps = json['result']['heaps'];
    int newSpace = heaps['new']['used'];
    int oldSpace = heaps['old']['used'];
    return newSpace + oldSpace;
  }

  /**
   * Send the server an 'analysis.setAnalysisRoots' command directing it to
   * analyze [sourceDirectory].
   */
  Future setAnalysisRoot() =>
      sendAnalysisSetAnalysisRoots([sourceDirectory.path], []);

  /**
   * The server is automatically started before every test.
   */
  @override
  Future setUp() {
    onAnalysisErrors.listen((AnalysisErrorsParams params) {
      currentAnalysisErrors[params.file] = params.errors;
    });
    onServerError.listen((ServerErrorParams params) {
      // A server error should never happen during an integration test.
      fail('${params.message}\n${params.stackTrace}');
    });
    Completer serverConnected = new Completer();
    onServerConnected.listen((_) {
      outOfTestExpect(serverConnected.isCompleted, isFalse);
      serverConnected.complete();
    });
    return startServer(servicesPort: vmServicePort).then((_) {
      server.listenToOutput(dispatchNotification);
      server.exitCode.then((_) {
        skipShutdown = true;
      });
      return serverConnected.future;
    });
  }

  /**
   * After every test, the server is stopped.
   */
  Future shutdown() async => await shutdownIfNeeded();

  /**
   * Enable [ServerService.STATUS] notifications so that [analysisFinished]
   * can be used.
   */
  Future subscribeToStatusNotifications() async {
    await sendServerSetSubscriptions([ServerService.STATUS]);
  }

  /**
   * Synchronously run the given [executable] with the given [arguments]. Return
   * the result of running the process.
   */
  ProcessResult _run(String executable, List<String> arguments) {
    return Process.runSync(executable, arguments,
        stderrEncoding: UTF8, stdoutEncoding: UTF8);
  }

  /**
   *  1. Start Analysis Server.
   *  2. Set the analysis [roots].
   *  3. Wait for analysis to complete.
   *  4. Record the heap size after analysis is finished.
   *  5. Shutdown.
   *  6. Go to (1).
   */
  static Future<List<int>> start_waitInitialAnalysis_shutdown(
      {List<String> roots, int numOfRepeats}) async {
    outOfTestExpect(roots, isNotNull, reason: 'roots');
    outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
    // Repeat.
    List<int> sizes = <int>[];
    for (int i = 0; i < numOfRepeats; i++) {
      AnalysisServerMemoryUsageTest test = new AnalysisServerMemoryUsageTest();
      // Initialize Analysis Server.
      await test.setUp();
      await test.subscribeToStatusNotifications();
      // Set roots and analyze.
      await test.sendAnalysisSetAnalysisRoots(roots, []);
      await test.analysisFinished;
      sizes.add(test.getMemoryUsage());
      // Stop the server.
      await test.shutdown();
    }
    return sizes;
  }
}
