// 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 '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';

/// 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.uri.isScheme('file')) {
        uri = source.uri.toString();
      } else {
        uri = sourceFactory.pathToUri(file).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);
  }
}
