// 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 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/protocol.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.getAnalysisContext(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;
      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;
      if (!_isInAnalysisRoot(filePath)) {
        return;
      }
      AnalysisContext context = server.getAnalysisContext(filePath);
      if (context == null) {
        return;
      }
      if (AnalysisEngine.isDartFileName(filePath)) {
        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());
      } else if (AnalysisEngine.isHtmlFileName(filePath)) {
        List<Source> libraries = context.getLibrariesReferencedFromHtml(source);
        server.sendNotification(new ExecutionLaunchDataParams(filePath,
            referencedFiles: _getFullNames(libraries)).toNotification());
      }
    });
  }

  /**
   * Return `true` if the given [filePath] represents a file that is in an
   * analysis root.
   */
  bool _isInAnalysisRoot(String filePath) =>
      server.contextDirectoryManager.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();
  }
}
