// Copyright (c) 2015, 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.

library analysis_server.src.domain_diagnostic;

import 'dart:collection';
import 'dart:core';

import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
import 'package:analyzer/src/task/driver.dart';
import 'package:analyzer/task/model.dart';

int _workItemCount(AnalysisContextImpl context) {
  AnalysisDriver driver = context.driver;
  List<WorkItem> items = driver.currentWorkOrder?.workItems;
  return items?.length ?? 0;
}

/// Instances of the class [DiagnosticDomainHandler] implement a
/// [RequestHandler] that handles requests in the `diagnostic` domain.
class DiagnosticDomainHandler implements RequestHandler {
  /// The name of the request used to get diagnostic information.
  static const String DIAGNOSTICS = 'diagnostic.getDiagnostics';

  /// The analysis server that is using this handler to process requests.
  final AnalysisServer server;

  /// Initialize a newly created handler to handle requests for the given
  /// [server].
  DiagnosticDomainHandler(this.server);

  /// Answer the `diagnostic.diagnostics` request.
  Response computeDiagnostics(Request request) {
    List<ContextData> infos = <ContextData>[];
    for (AnalysisContext context in server.analysisContexts) {
      infos.add(extractData(context));
    }
    return new DiagnosticGetDiagnosticsResult(infos).toResponse(request.id);
  }

  /// Extract context data from the given [context].
  ContextData extractData(AnalysisContext context) {
    int explicitFiles = 0;
    int implicitFiles = 0;
    int workItems = 0;
    Set<String> exceptions = new HashSet<String>();
    if (context is AnalysisContextImpl) {
      workItems = _workItemCount(context);
      var cache = context.analysisCache;
      if (cache is AnalysisCache) {
        Set<AnalysisTarget> countedTargets = new HashSet<AnalysisTarget>();
        MapIterator<AnalysisTarget, CacheEntry> iterator = cache.iterator();
        while (iterator.moveNext()) {
          AnalysisTarget target = iterator.key;
          if (countedTargets.add(target)) {
            CacheEntry cacheEntry = iterator.value;
            if (cacheEntry == null) {
              throw new StateError(
                  "mutated cache key detected: $target (${target.runtimeType})");
            }
            if (target is Source) {
              if (cacheEntry.explicitlyAdded) {
                explicitFiles++;
              } else {
                implicitFiles++;
              }
            }
            // Caught exceptions.
            if (cacheEntry.exception != null) {
              exceptions.add(cacheEntry.exception.toString());
            }
          }
        }
      }
    }
    return new ContextData(context.name, explicitFiles, implicitFiles,
        workItems, exceptions.toList());
  }

  @override
  Response handleRequest(Request request) {
    try {
      String requestName = request.method;
      if (requestName == DIAGNOSTICS) {
        return computeDiagnostics(request);
      }
    } on RequestFailure catch (exception) {
      return exception.response;
    }
    return null;
  }
}
