// 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.

library domain.execution;

import 'dart:async';
import 'dart:collection';
import 'dart:core' hide Resource;

import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/constants.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';

/**
 * Instances of the class [ExecutionDomainHandler] implement a [RequestHandler]
 * that handles requests in the `execution` domain.
 */
class ExecutionDomainHandler implements RequestHandler {
  /**
   * The analysis server that is using this handler to process requests.
   */
  final AnalysisServer server;

  /**
   * The next execution context identifier to be returned.
   */
  int nextContextId = 0;

  /**
   * A table mapping execution context id's to the root of the context.
   */
  Map<String, String> contextMap = new HashMap<String, String>();

  /**
   * The subscription to the 'onAnalysisComplete' events,
   * used to send notifications when
   */
  StreamSubscription onFileAnalyzed;

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

  /**
   * Implement the `execution.createContext` request.
   */
  Response createContext(Request request) {
    String file =
        new ExecutionCreateContextParams.fromRequest(request).contextRoot;
    String contextId = (nextContextId++).toString();
    contextMap[contextId] = file;
    return new ExecutionCreateContextResult(contextId).toResponse(request.id);
  }

  /**
   * Implement the `execution.deleteContext` request.
   */
  Response deleteContext(Request request) {
    String contextId = new ExecutionDeleteContextParams.fromRequest(request).id;
    contextMap.remove(contextId);
    return new ExecutionDeleteContextResult().toResponse(request.id);
  }

  @override
  Response handleRequest(Request request) {
    try {
      String requestName = request.method;
      if (requestName == EXECUTION_CREATE_CONTEXT) {
        return createContext(request);
      } else if (requestName == EXECUTION_DELETE_CONTEXT) {
        return deleteContext(request);
      } else if (requestName == EXECUTION_MAP_URI) {
        return mapUri(request);
      } else if (requestName == EXECUTION_SET_SUBSCRIPTIONS) {
        return setSubscriptions(request);
      }
    } on RequestFailure catch (exception) {
      return exception.response;
    }
    return null;
  }

  /**
   * Implement the 'execution.mapUri' request.
   */
  Response mapUri(Request request) {
    ExecutionMapUriParams params =
        new ExecutionMapUriParams.fromRequest(request);
    String contextId = params.id;
    String path = contextMap[contextId];
    if (path == null) {
      return new Response.invalidParameter(request, 'id',
          'There is no execution context with an id of $contextId');
    }
    AnalysisContext context = server.getContainingContext(path);
    if (context == null) {
      return new Response.invalidExecutionContext(request, contextId);
    }
    String file = params.file;
    String uri = params.uri;
    if (file != null) {
      if (uri != null) {
        return new Response.invalidParameter(request, 'file',
            'Either file or uri must be provided, but not both');
      }
      Resource resource = server.resourceProvider.getResource(file);
      if (!resource.exists) {
        return new Response.invalidParameter(request, 'file', 'Must exist');
      } else if (resource is! File) {
        return new Response.invalidParameter(
            request, 'file', 'Must not refer to a directory');
      }
      ContextSourcePair contextSource = server.getContextSourcePair(file);
      Source source = contextSource.source;
      if (source.uriKind != UriKind.FILE_URI) {
        uri = source.uri.toString();
      } else {
        uri = context.sourceFactory.restoreUri(source).toString();
      }
      return new ExecutionMapUriResult(uri: uri).toResponse(request.id);
    } else if (uri != null) {
      Source source = context.sourceFactory.forUri(uri);
      if (source == null) {
        return new Response.invalidParameter(request, 'uri', 'Invalid URI');
      }
      file = source.fullName;
      return new ExecutionMapUriResult(file: file).toResponse(request.id);
    }
    return new Response.invalidParameter(
        request, 'file', 'Either file or uri must be provided');
  }

  /**
   * Implement the 'execution.setSubscriptions' request.
   */
  Response setSubscriptions(Request request) {
    List<ExecutionService> subscriptions =
        new ExecutionSetSubscriptionsParams.fromRequest(request).subscriptions;
    if (subscriptions.contains(ExecutionService.LAUNCH_DATA)) {
      if (onFileAnalyzed == null) {
        onFileAnalyzed = server.onFileAnalyzed.listen(_fileAnalyzed);
        _reportCurrentFileStatus();
      }
    } else {
      if (onFileAnalyzed != null) {
        onFileAnalyzed.cancel();
        onFileAnalyzed = null;
      }
    }
    return new ExecutionSetSubscriptionsResult().toResponse(request.id);
  }

  void _fileAnalyzed(ChangeNotice notice) {
    ServerPerformanceStatistics.executionNotifications.makeCurrentWhile(() {
      Source source = notice.source;
      String filePath = source.fullName;
      // check files
      bool isDartFile = notice.resolvedDartUnit != null;
      if (!isDartFile) {
        return;
      }
      // prepare context
      AnalysisContext context = server.getContainingContext(filePath);
      if (context == null) {
        return;
      }
      // analyze the file
      if (isDartFile) {
        ExecutableKind kind = ExecutableKind.NOT_EXECUTABLE;
        if (context.isClientLibrary(source)) {
          kind = ExecutableKind.CLIENT;
          if (context.isServerLibrary(source)) {
            kind = ExecutableKind.EITHER;
          }
        } else if (context.isServerLibrary(source)) {
          kind = ExecutableKind.SERVER;
        }
        server.sendNotification(
            new ExecutionLaunchDataParams(filePath, kind: kind)
                .toNotification());
      }
    });
  }

  /**
   * Return `true` if the given [filePath] represents a file that is in an
   * analysis root.
   */
  bool _isInAnalysisRoot(String filePath) =>
      server.contextManager.isInAnalysisRoot(filePath);

  void _reportCurrentFileStatus() {
    for (AnalysisContext context in server.getAnalysisContexts()) {
      List<Source> librarySources = context.librarySources;
      List<Source> clientSources = context.launchableClientLibrarySources;
      List<Source> serverSources = context.launchableServerLibrarySources;
      for (Source source in clientSources) {
        if (serverSources.remove(source)) {
          _sendKindNotification(source.fullName, ExecutableKind.EITHER);
        } else {
          _sendKindNotification(source.fullName, ExecutableKind.CLIENT);
        }
        librarySources.remove(source);
      }
      for (Source source in serverSources) {
        _sendKindNotification(source.fullName, ExecutableKind.SERVER);
        librarySources.remove(source);
      }
      for (Source source in librarySources) {
        _sendKindNotification(source.fullName, ExecutableKind.NOT_EXECUTABLE);
      }
      for (Source source in context.htmlSources) {
        String filePath = source.fullName;
        if (_isInAnalysisRoot(filePath)) {
          List<Source> libraries =
              context.getLibrariesReferencedFromHtml(source);
          server.sendNotification(new ExecutionLaunchDataParams(filePath,
              referencedFiles: _getFullNames(libraries)).toNotification());
        }
      }
    }
  }

  /**
   * Send a notification indicating the [kind] of the file with the given
   * [filePath], but only if the file is in an analysis root.
   */
  void _sendKindNotification(String filePath, ExecutableKind kind) {
    if (_isInAnalysisRoot(filePath)) {
      server.sendNotification(
          new ExecutionLaunchDataParams(filePath, kind: kind).toNotification());
    }
  }

  static List<String> _getFullNames(List<Source> sources) {
    return sources.map((Source source) => source.fullName).toList();
  }
}
