// 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);
  }
}
