// 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:collection';
import 'dart:core';

import 'package:analysis_server/protocol/protocol_constants.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analyzer/file_system/file_system.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.
  final Map<String, String> contextMap = HashMap<String, String>();

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

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

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

  /// Implement the 'execution.getSuggestions' request.
  void getSuggestions(Request request) async {
//    var params = new ExecutionGetSuggestionsParams.fromRequest(request);
//    var computer = new RuntimeCompletionComputer(
//        server.resourceProvider,
//        server.fileContentOverlay,
//        server.getAnalysisDriver(params.contextFile),
//        params.code,
//        params.offset,
//        params.contextFile,
//        params.contextOffset,
//        params.variables,
//        params.expressions);
//    RuntimeCompletionResult completionResult = await computer.compute();
//
//    // Send the response.
//    var result = new ExecutionGetSuggestionsResult(
//        suggestions: completionResult.suggestions,
//        expressions: completionResult.expressions);
    // TODO(brianwilkerson) Re-enable this functionality after implementing a
    // way of computing suggestions that is compatible with AnalysisSession.
    var result = ExecutionGetSuggestionsResult(
        suggestions: <CompletionSuggestion>[],
        expressions: <RuntimeCompletionExpression>[]);
    server.sendResponse(result.toResponse(request.id));
  }

  @override
  Response handleRequest(Request request) {
    try {
      var requestName = request.method;
      if (requestName == EXECUTION_REQUEST_CREATE_CONTEXT) {
        return createContext(request);
      } else if (requestName == EXECUTION_REQUEST_DELETE_CONTEXT) {
        return deleteContext(request);
      } else if (requestName == EXECUTION_REQUEST_GET_SUGGESTIONS) {
        getSuggestions(request);
        return Response.DELAYED_RESPONSE;
      } else if (requestName == EXECUTION_REQUEST_MAP_URI) {
        return mapUri(request);
      } else if (requestName == EXECUTION_REQUEST_SET_SUBSCRIPTIONS) {
        return setSubscriptions(request);
      }
    } on RequestFailure catch (exception) {
      return exception.response;
    }
    return null;
  }

  /// Implement the 'execution.mapUri' request.
  Response mapUri(Request request) {
    var params = ExecutionMapUriParams.fromRequest(request);
    var contextId = params.id;
    var path = contextMap[contextId];
    if (path == null) {
      return Response.invalidParameter(request, 'id',
          'There is no execution context with an id of $contextId');
    }

    var driver = server.getAnalysisDriver(path);
    if (driver == null) {
      return Response.invalidExecutionContext(request, contextId);
    }
    var sourceFactory = driver.sourceFactory;

    var file = params.file;
    var uri = params.uri;
    if (file != null) {
      if (uri != null) {
        return Response.invalidParameter(request, 'file',
            'Either file or uri must be provided, but not both');
      }
      var resource = server.resourceProvider.getResource(file);
      if (!resource.exists) {
        return Response.invalidParameter(request, 'file', 'Must exist');
      } else if (resource is! File) {
        return Response.invalidParameter(
            request, 'file', 'Must not refer to a directory');
      }

      var source = driver.fsState.getFileForPath(file).source;
      if (source.uriKind != UriKind.FILE_URI) {
        uri = source.uri.toString();
      } else {
        uri = sourceFactory.restoreUri(source).toString();
      }
      return ExecutionMapUriResult(uri: uri).toResponse(request.id);
    } else if (uri != null) {
      var source = sourceFactory.forUri(uri);
      if (source == null) {
        return Response.invalidParameter(request, 'uri', 'Invalid URI');
      }
      file = source.fullName;
      return ExecutionMapUriResult(file: file).toResponse(request.id);
    }
    return Response.invalidParameter(
        request, 'file', 'Either file or uri must be provided');
  }

  /// Implement the 'execution.setSubscriptions' request.
  Response setSubscriptions(Request request) {
    // Under the analysis driver, setSubscriptions() becomes a no-op.
    return ExecutionSetSubscriptionsResult().toResponse(request.id);
  }
}
