// Copyright (c) 2015, 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:async';
import 'dart:convert';
import 'dart:io';

import 'package:analysis_server/protocol/protocol.dart';
import 'package:analysis_server/protocol/protocol_constants.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:logging/logging.dart';
import 'package:path/path.dart' as path;

import 'instrumentation_input_converter.dart';
import 'log_file_input_converter.dart';
import 'operation.dart';

/// Common input converter superclass for sharing implementation.
abstract class CommonInputConverter extends Converter<String, Operation?> {
  static final ERROR_PREFIX = 'Server responded with an error: ';
  final Logger logger = Logger('InstrumentationInputConverter');
  final Set<String> eventsSeen = <String>{};

  /// A mapping from request/response id to request json
  /// for those requests for which a response has not been processed.
  final Map<String, Object?> requestMap = {};

  /// A mapping from request/response id to a completer
  /// for those requests for which a response has not been processed.
  /// The completer is called with the actual json response
  /// when it becomes available.
  final Map<String, Completer> responseCompleters = {};

  /// A mapping from request/response id to the actual response result
  /// for those responses that have not been processed.
  final Map<String, Object?> responseMap = {};

  /// A mapping of current overlay content
  /// parallel to what is in the analysis server
  /// so that we can update the file system.
  final Map<String, String> overlays = {};

  /// The prefix used to determine if a request parameter is a file path.
  final String rootPrefix = path.rootPrefix(path.current);

  /// A mapping of source path prefixes
  /// from location where instrumentation or log file was generated
  /// to the target location of the source using during performance measurement.
  final PathMap srcPathMap;

  /// The root directory for all source being modified
  /// during performance measurement.
  final String tmpSrcDirPath;

  CommonInputConverter(this.tmpSrcDirPath, this.srcPathMap);

  Map<String, Object?> asMap(dynamic value) => value as Map<String, Object?>;

  Map<String, Object?>? asMap2(dynamic value) => value as Map<String, Object?>?;

  /// Return an operation for the notification or `null` if none.
  Operation? convertNotification(Map<String, dynamic> json) {
    var event = json['event'] as String;
    if (event == SERVER_NOTIFICATION_STATUS) {
      // {"event":"server.status","params":{"analysis":{"isAnalyzing":false}}}
      var params = asMap2(json['params']);
      if (params != null) {
        var analysis = asMap2(params['analysis']);
        if (analysis != null && analysis['isAnalyzing'] == false) {
          return WaitForAnalysisCompleteOperation();
        }
      }
    }
    if (event == SERVER_NOTIFICATION_CONNECTED) {
      // {"event":"server.connected","params":{"version":"1.7.0"}}
      return StartServerOperation();
    }
    if (eventsSeen.add(event)) {
      logger.log(Level.INFO, 'Ignored notification: $event\n  $json');
    }
    return null;
  }

  /// Return an operation for the request or `null` if none.
  Operation convertRequest(Map<String, Object?> origJson) {
    var json = asMap(translateSrcPaths(origJson));
    requestMap[json['id'] as String] = json;
    var method = json['method'] as String;
    // Sanity check operations that modify source
    // to ensure that the operation is on source in temp space
    if (method == ANALYSIS_REQUEST_UPDATE_CONTENT) {
      // Track overlays in parallel with the analysis server
      // so that when an overlay is removed, the file can be updated on disk
      var request = Request.fromJson(json)!;
      var params = AnalysisUpdateContentParams.fromRequest(request);
      params.files.forEach((String filePath, change) {
        if (change is AddContentOverlay) {
          var content = change.content;
          overlays[filePath] = content;
        } else if (change is ChangeContentOverlay) {
          var content = overlays[filePath];
          if (content == null) {
            throw 'expected cached overlay content\n$json';
          }
          overlays[filePath] = SourceEdit.applySequence(content, change.edits);
        } else if (change is RemoveContentOverlay) {
          var content = overlays.remove(filePath);
          if (content == null) {
            throw 'expected cached overlay content\n$json';
          }
          if (!path.isWithin(tmpSrcDirPath, filePath)) {
            throw 'found path referencing source outside temp space\n$filePath\n$json';
          }
          File(filePath).writeAsStringSync(content);
        } else {
          throw 'unknown overlay change $change\n$json';
        }
      });
      return RequestOperation(this, json);
    }
    // Track performance for completion notifications
    if (method == COMPLETION_REQUEST_GET_SUGGESTIONS) {
      return CompletionRequestOperation(this, json);
    }
    // TODO(danrubel) replace this with code
    // that just forwards the translated request
    if (method == ANALYSIS_REQUEST_GET_HOVER ||
        method == ANALYSIS_REQUEST_SET_ANALYSIS_ROOTS ||
        method == ANALYSIS_REQUEST_SET_PRIORITY_FILES ||
        method == ANALYSIS_REQUEST_SET_SUBSCRIPTIONS ||
        method == ANALYSIS_REQUEST_UPDATE_OPTIONS ||
        method == EDIT_REQUEST_GET_ASSISTS ||
        method == EDIT_REQUEST_GET_AVAILABLE_REFACTORINGS ||
        method == EDIT_REQUEST_GET_FIXES ||
        method == EDIT_REQUEST_GET_REFACTORING ||
        method == EDIT_REQUEST_SORT_MEMBERS ||
        method == EXECUTION_REQUEST_CREATE_CONTEXT ||
        method == EXECUTION_REQUEST_DELETE_CONTEXT ||
        method == EXECUTION_REQUEST_MAP_URI ||
        method == EXECUTION_REQUEST_SET_SUBSCRIPTIONS ||
        method == SEARCH_REQUEST_FIND_ELEMENT_REFERENCES ||
        method == SEARCH_REQUEST_FIND_MEMBER_DECLARATIONS ||
        method == SERVER_REQUEST_GET_VERSION ||
        method == SERVER_REQUEST_SET_SUBSCRIPTIONS) {
      return RequestOperation(this, json);
    }
    throw 'unknown request: $method\n  $json';
  }

  /// Return an operation for the recorded/expected response.
  Operation convertResponse(Map<String, dynamic> json) {
    return ResponseOperation(this, asMap(requestMap.remove(json['id'])),
        asMap(translateSrcPaths(json)));
  }

  void logOverlayContent() {
    logger.log(Level.WARNING, '${overlays.length} overlays');
    var allPaths = overlays.keys.toList()..sort();
    for (var filePath in allPaths) {
      logger.log(Level.WARNING, 'overlay $filePath\n${overlays[filePath]}');
    }
  }

  /// Process an error response from the server by either
  /// completing the associated completer in the [responseCompleters]
  /// or stashing it in [responseMap] if no completer exists.
  void processErrorResponse(String id, exception) {
    var result = exception;
    if (exception is UnimplementedError) {
      var message = exception.message;
      if (message!.startsWith(ERROR_PREFIX)) {
        result = json.decode(message.substring(ERROR_PREFIX.length));
      }
    }
    processResponseResult(id, result);
  }

  /// Process the expected response by completing the given completer
  /// with the result if it has already been received,
  /// or caching the completer to be completed when the server
  /// returns the associated result.
  /// Return a future that completes when the response is received
  /// or `null` if the response has already been received
  /// and the completer completed.
  Future<void>? processExpectedResponse(String id, Completer completer) {
    if (responseMap.containsKey(id)) {
      logger.log(Level.INFO, 'processing cached response $id');
      completer.complete(responseMap.remove(id));
      return null;
    } else {
      logger.log(Level.INFO, 'waiting for response $id');
      responseCompleters[id] = completer;
      return completer.future;
    }
  }

  /// Process a success response result from the server by either
  /// completing the associated completer in the [responseCompleters]
  /// or stashing it in [responseMap] if no completer exists.
  /// The response result may be `null`.
  void processResponseResult(String id, result) {
    var completer = responseCompleters[id];
    if (completer != null) {
      logger.log(Level.INFO, 'processing response $id');
      completer.complete(result);
    } else {
      logger.log(Level.INFO, 'caching response $id');
      responseMap[id] = result;
    }
  }

  /// Recursively translate source paths in the specified JSON to reference
  /// the temporary source used during performance measurement rather than
  /// the original source when the instrumentation or log file was generated.
  Object? translateSrcPaths(Object? json) {
    if (json is String) {
      return srcPathMap.translate(json);
    }
    if (json is List) {
      var result = <Object?>[];
      for (var i = 0; i < json.length; ++i) {
        result.add(translateSrcPaths(json[i] as Object?));
      }
      return result;
    }
    if (json is Map) {
      var result = <String, Object?>{};
      json.forEach((origKey, value) {
        result[translateSrcPaths(origKey) as String] = translateSrcPaths(value);
      });
      return result;
    }
    return json;
  }
}

/// [InputConverter] converts an input stream
/// into a series of operations to be sent to the analysis server.
/// The input stream can be either an instrumentation or log file.
class InputConverter extends Converter<String, Operation?> {
  final Logger logger = Logger('InputConverter');

  /// A mapping of source path prefixes
  /// from location where instrumentation or log file was generated
  /// to the target location of the source using during performance measurement.
  final PathMap srcPathMap;

  /// The root directory for all source being modified
  /// during performance measurement.
  final String tmpSrcDirPath;

  /// The number of lines read before the underlying converter was determined
  /// or the end of file was reached.
  int _headerLineCount = 0;

  /// The underlying converter used to translate lines into operations
  /// or `null` if it has not yet been determined.
  Converter<String, Operation?>? _converter;

  /// [_active] is `true` if converting lines to operations
  /// or `false` if an exception has occurred.
  bool _active = true;

  InputConverter(this.tmpSrcDirPath, this.srcPathMap);

  @override
  Operation? convert(String line) {
    if (!_active) {
      return null;
    }
    try {
      var converter = _getConverter(line);
      if (converter == null) {
        logger.log(Level.INFO, 'skipped input line: $line');
        return null;
      }
      return converter.convert(line);
    } catch (_) {
      _active = false;
      rethrow;
    }
  }

  @override
  _InputSink startChunkedConversion(outSink) {
    return _InputSink(this, outSink);
  }

  /// Return the previously determined converter, or determine it from the
  /// given [line]. Return `null` if cannot be determined yet. Throw an
  /// exception if could not be determined after some number of tries.
  Converter<String, Operation?>? _getConverter(String line) {
    var converter = _converter;
    if (converter != null) {
      return converter;
    }

    if (_headerLineCount++ == 20) {
      throw 'Failed to determine input file format';
    }

    if (InstrumentationInputConverter.isFormat(line)) {
      _converter = InstrumentationInputConverter(tmpSrcDirPath, srcPathMap);
    } else if (LogFileInputConverter.isFormat(line)) {
      _converter = LogFileInputConverter(tmpSrcDirPath, srcPathMap);
    }

    return _converter;
  }
}

/// A container of [PathMapEntry]s used to translate a source path in the log
/// before it is sent to the analysis server.
class PathMap {
  final List<PathMapEntry> entries = [];

  void add(String oldSrcPrefix, String newSrcPrefix) {
    entries.add(PathMapEntry(oldSrcPrefix, newSrcPrefix));
  }

  String translate(String original) {
    var result = original;
    for (var entry in entries) {
      result = entry.translate(result);
    }
    return result;
  }
}

/// An entry in [PathMap] used to translate a source path in the log
/// before it is sent to the analysis server.
class PathMapEntry {
  final String oldSrcPrefix;
  final String newSrcPrefix;

  PathMapEntry(this.oldSrcPrefix, this.newSrcPrefix);

  String translate(String original) {
    return original.startsWith(oldSrcPrefix)
        ? '$newSrcPrefix${original.substring(oldSrcPrefix.length)}'
        : original;
  }
}

class _InputSink extends ChunkedConversionSink<String> {
  final Converter<String, Operation?> converter;
  final Sink<Operation?> outSink;

  _InputSink(this.converter, this.outSink);

  @override
  void add(String line) {
    var op = converter.convert(line);
    if (op != null) {
      outSink.add(op);
    }
  }

  @override
  void close() {
    outSink.close();
  }
}
