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

import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:charcode/charcode.dart';
import 'package:cli_util/cli_logging.dart';
import 'package:meta/meta.dart';
import 'package:nnbd_migration/src/edit_plan.dart';
import 'package:nnbd_migration/src/front_end/migration_info.dart';
import 'package:nnbd_migration/src/front_end/migration_state.dart';
import 'package:nnbd_migration/src/front_end/path_mapper.dart';
import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
import 'package:nnbd_migration/src/hint_action.dart';
import 'package:nnbd_migration/src/preview/dart_file_page.dart';
import 'package:nnbd_migration/src/preview/dart_logo_page.dart';
import 'package:nnbd_migration/src/preview/exception_page.dart';
import 'package:nnbd_migration/src/preview/highlight_css_page.dart';
import 'package:nnbd_migration/src/preview/highlight_js_page.dart';
import 'package:nnbd_migration/src/preview/http_preview_server.dart';
import 'package:nnbd_migration/src/preview/index_file_page.dart';
import 'package:nnbd_migration/src/preview/material_icons_page.dart';
import 'package:nnbd_migration/src/preview/navigation_tree_page.dart';
import 'package:nnbd_migration/src/preview/not_found_page.dart';
import 'package:nnbd_migration/src/preview/pages.dart';
import 'package:nnbd_migration/src/preview/preview_page.dart';
import 'package:nnbd_migration/src/preview/region_page.dart';
import 'package:nnbd_migration/src/preview/roboto_mono_page.dart';
import 'package:nnbd_migration/src/preview/roboto_page.dart';
import 'package:nnbd_migration/src/preview/unauthorized_page.dart';

// The randomly generated auth token used to access the preview site.
String _makeAuthToken() {
  final kTokenByteSize = 8;
  var bytes = Uint8List(kTokenByteSize);
  var random = Random.secure();
  for (var i = 0; i < kTokenByteSize; i++) {
    bytes[i] = random.nextInt(256);
  }
  return base64Url.encode(bytes);
}

/// A plan for an incremental migration.
///
/// This plan uses [UnitMigrationStatus]es from [NavigationTreeNode]s to apply
/// different edits to different files:
///
/// * migrating files will be edited according to a [SourceFileEdit],
/// * newly opted out files will be prepended with a Dart Language Version
///   comment specifying "2.9",
/// * already opted out files will remain unchanged.
class IncrementalPlan {
  static final _nonWhitespaceChar = RegExp(r'\S');
  final MigrationInfo? migrationInfo;
  final Map<String?, UnitInfo> unitInfoMap;
  final PathMapper? pathMapper;
  final List<SourceFileEdit> edits;
  final Logger? logger;

  /// The set of units which are to be opted out in this migration.
  final Set<String?> optOutUnitPaths;

  /// Creates a new [IncrementalPlan], extracting all of the paths which are
  /// "opting out" from [navigationTree].
  factory IncrementalPlan(
      MigrationInfo? migrationInfo,
      Map<String?, UnitInfo> unitInfoMap,
      PathMapper? pathMapper,
      List<SourceFileEdit> edits,
      Iterable<NavigationTreeNode> navigationTree,
      Logger? logger) {
    var optOutUnitPaths = <String?>{};
    void addUnitsToOptOut(NavigationTreeNode entity) {
      if (entity is NavigationTreeDirectoryNode) {
        for (var child in entity.subtree!) {
          addUnitsToOptOut(child);
        }
      } else {
        if (entity.migrationStatus == UnitMigrationStatus.optingOut) {
          optOutUnitPaths.add(entity.path);
        }
      }
    }

    for (var entity in navigationTree) {
      addUnitsToOptOut(entity);
    }

    return IncrementalPlan._(
        migrationInfo, unitInfoMap, pathMapper, edits, optOutUnitPaths, logger);
  }

  IncrementalPlan._(this.migrationInfo, this.unitInfoMap, this.pathMapper,
      this.edits, this.optOutUnitPaths, this.logger);

  /// Applies this migration to disk.
  void apply() {
    logger!.stdout('Applying migration suggestions to disk...');
    var migratedFiles = <String>[];
    for (final fileEdit in edits) {
      var unit = unitInfoMap[fileEdit.file];
      // Decide whether to opt out; default to `false` files not included in
      // [edits], like [pubspec.yaml].
      var unitIsOptOut = unit != null
          ? optOutUnitPaths.contains(migrationInfo!.computeName(unit))
          : false;
      if (!unitIsOptOut) {
        final file = pathMapper!.provider.getFile(fileEdit.file);
        var code = file.exists ? file.readAsStringSync() : '';
        code = SourceEdit.applySequence(code, fileEdit.edits);
        file.writeAsStringSync(code);
        migratedFiles.add(migrationInfo!.relativePathFromRoot(fileEdit.file));
      }
    }

    // A file which is to be opted out may not be found in [edits], if all types
    // were to be made non-nullable, etc. Iterate over [optOutUnitPaths] instead
    // of [edits] to opt files out.
    var newlyOptedOutFiles = <String?>[];
    var keptOptedOutFiles = <String?>[];
    for (var optOutUnitPath in optOutUnitPaths) {
      var absolutePath = migrationInfo!.absolutePathFromRoot(optOutUnitPath);
      var unit = unitInfoMap[absolutePath]!;
      if (unit.wasExplicitlyOptedOut) {
        // This unit was explicitly opted out of null safety with a Dart
        // Language version comment. Leave the unit be.
        keptOptedOutFiles.add(optOutUnitPath);
      } else {
        // This unit was not yet migrated at the start, was not explicitly
        // opted out at the start, and is being opted out now. Add a Dart
        // Language version comment.
        final file = pathMapper!.provider.getFile(absolutePath);
        var code = file.exists ? file.readAsStringSync() : '';
        file.writeAsStringSync(optCodeOutOfNullSafety(code));
        newlyOptedOutFiles.add(optOutUnitPath);
      }
    }

    _logFileStatus(migratedFiles, (text) => 'Migrated $text');
    _logFileStatus(
        newlyOptedOutFiles,
        (text) =>
            'Opted $text out of null safety with a new Dart language version '
            'comment');
    _logFileStatus(
        keptOptedOutFiles, (text) => 'Kept $text opted out of null safety');
  }

  void _logFileStatus(
      List<String?> files, String Function(String text) template) {
    if (files.isNotEmpty) {
      var count = files.length;
      if (count <= 20) {
        var s = count > 1 ? 's' : '';
        var text = '$count file$s';
        logger!.stdout('${template(text)}:');
        for (var path in files) {
          logger!.stdout('    $path');
        }
      } else {
        var text = '$count files';
        logger!.stdout('${template(text)}.');
      }
    }
  }

  @visibleForTesting
  static String optCodeOutOfNullSafety(String code) {
    var newline = '\n';
    var length = code.length;

    if (length == 0) {
      return '// @dart=2.9';
    }

    var index = 0;

    // Returns the next line and updates [index].
    //
    // After this function returns, [index] points to the character after the
    // end of the line which was returned.
    String getLine() {
      var nextIndex = code.indexOf('\n', index);
      if (nextIndex < 0) {
        // Last line.
        var line = code.substring(index);
        index = length;
        return line;
      }
      var line = code.substring(index, nextIndex);
      index = nextIndex + 1;
      return line;
    }

    // Skip past blank lines.
    var line = getLine();
    if (code.codeUnitAt(index - 1) == $lf) {
      if (index - 2 >= 0 && code.codeUnitAt(index - 2) == $cr) {
        // Looks like Windows-style line endings ("\r\n"). Use "\r\n" for all
        // inserted line endings.
        newline = '\r\n';
      }
    }
    var lineStart = line.indexOf(_nonWhitespaceChar);
    while (lineStart < 0) {
      line = getLine();
      if (index == length) {
        // [code] consists _only_ of blank lines.
        return '// @dart=2.9$newline$newline$code';
      }
      lineStart = line.indexOf(_nonWhitespaceChar);
    }

    // [line] is the first non-blank line.
    if (line.length > lineStart + 1 &&
        line.codeUnitAt(lineStart) == $slash &&
        line.codeUnitAt(lineStart + 1) == $slash) {
      // [line] is a comment.

      if (index == length) {
        // [code] consists _only_ of one comment line.
        return '$code$newline$newline// @dart=2.9$newline';
      }
      var previousLineIndex = index;
      String newlinesAfterDlvc;
      while (true) {
        previousLineIndex = index;
        line = getLine();
        lineStart = line.indexOf(_nonWhitespaceChar);
        if (lineStart < 0) {
          // Line of zero-or-more whitespace; end of block comment.
          newlinesAfterDlvc = newline;
          break;
        }
        if (line.length <= lineStart + 1) {
          // Only one character; not a comment; end of block comment.
          newlinesAfterDlvc = '$newline$newline';
          break;
        }
        if (line.codeUnitAt(lineStart) == $slash &&
            line.codeUnitAt(lineStart + 1) == $slash) {
          // Comment line.
          if (index == length) {
            // [code] consists _only_ of this block comment.
            return '$code$newline$newline// @dart=2.9$newline';
          }
          continue;
        } else {
          // Non-blank, non-comment line.
          newlinesAfterDlvc = '$newline$newline';
          break;
        }
      }
      // [previousLineIndex] points to the start of [line], which is the first
      // non-comment line following the first comment.
      return '${code.substring(0, previousLineIndex)}$newline'
          '// @dart=2.9$newlinesAfterDlvc'
          '${code.substring(previousLineIndex)}';
    } else {
      // [code] does not start with a block comment.
      return '// @dart=2.9$newline$newline$code';
    }
  }
}

/// The site used to serve pages for the preview tool.
class PreviewSite extends Site
    implements AbstractGetHandler, AbstractPostHandler {
  /// The path of the CSS page used to style the semantic highlighting within a
  /// Dart file.
  static const highlightCssPath = '/highlight.css';

  /// The path of the JS page used to associate highlighting within a Dart file.
  static const highlightJsPath = '/highlight.pack.js';

  /// The path of the Dart logo displayed in the toolbar.
  static const dartLogoPath = '/dart_192.png';

  /// The path of the Material icons font.
  static const materialIconsPath = '/MaterialIconsRegular.ttf';

  /// The path of the Roboto font.
  static const robotoFontPath = '/RobotoRegular.ttf';

  /// The path of the Roboto Mono font.
  static const robotoMonoFontPath = '/RobotoMonoRegular.ttf';

  static const navigationTreePath = '/_preview/navigationTree.json';

  static const applyHintPath = '/apply-hint';

  static const applyMigrationPath = '/apply-migration';

  static const rerunMigrationPath = '/rerun-migration';

  /// The state of the migration being previewed.
  MigrationState? migrationState;

  /// A table mapping the paths of files to the information about the
  /// compilation units at those paths.
  final Map<String?, UnitInfo> unitInfoMap = {};

  // A function provided by DartFix to rerun the migration.
  final Future<MigrationState?> Function() rerunFunction;

  /// Callback function that should be invoked after successfully applying
  /// migration.
  final void Function() applyHook;

  final Logger? logger;

  final String serviceAuthToken = _makeAuthToken();

  /// Initialize a newly created site to serve a preview of the results of an
  /// NNBD migration.
  PreviewSite(
      this.migrationState, this.rerunFunction, this.applyHook, this.logger)
      : super('NNBD Migration Preview') {
    reset();
  }

  /// Return the information about the migration that will be used to serve up
  /// pages.
  MigrationInfo? get migrationInfo => migrationState!.migrationInfo;

  /// Return the path mapper used to map paths from the unit infos to the paths
  /// being served.
  PathMapper? get pathMapper => migrationState!.pathMapper;

  @override
  Page createExceptionPage(String message, StackTrace trace) {
    // Use createExceptionPageWithPath instead.
    throw UnimplementedError();
  }

  /// Return a page used to display an exception that occurred while attempting
  /// to render another page. The [path] is the path to the page that was being
  /// rendered when the exception was thrown. The [message] and [stackTrace] are
  /// those from the exception.
  Page createExceptionPageWithPath(
      String path, String message, StackTrace stackTrace) {
    return ExceptionPage(this, path, message, stackTrace);
  }

  /// Return a page used to display an exception that occurred while attempting
  /// to render another page. The [path] is the path to the page that was being
  /// rendered when the exception was thrown. The [message] and [stackTrace] are
  /// those from the exception.
  Page createJsonExceptionResponse(
      String path, String message, StackTrace stackTrace) {
    return ExceptionPage(this, path, message, stackTrace);
  }

  Page createUnauthorizedPage(String unauthorizedPath) {
    return UnauthorizedPage(this, unauthorizedPath.substring(1));
  }

  @override
  Page createUnknownPage(String unknownPath) {
    return NotFoundPage(this, unknownPath.substring(1));
  }

  @override
  Future<void> handleGetRequest(HttpRequest request) async {
    var uri = request.uri;
    var path = uri.path;
    var decodedPath = pathMapper!.reverseMap(uri);
    try {
      if (path == highlightCssPath) {
        // Note: `return await` needed due to
        // https://github.com/dart-lang/sdk/issues/39204
        return await respond(request, HighlightCssPage(this));
      } else if (path == highlightJsPath) {
        // Note: `return await` needed due to
        // https://github.com/dart-lang/sdk/issues/39204
        return await respond(request, HighlightJSPage(this));
      } else if (path == navigationTreePath) {
        // Note: `return await` needed due to
        // https://github.com/dart-lang/sdk/issues/39204
        return await respond(request, NavigationTreePage(this));
      } else if (path == dartLogoPath) {
        // Note: `return await` needed due to
        // https://github.com/dart-lang/sdk/issues/39204
        return await respond(request, DartLogoPage(this));
      } else if (path == materialIconsPath) {
        // Note: `return await` needed due to
        // https://github.com/dart-lang/sdk/issues/39204
        return await respond(request, MaterialIconsPage(this));
      } else if (path == robotoFontPath) {
        // Note: `return await` needed due to
        // https://github.com/dart-lang/sdk/issues/39204
        return await respond(request, RobotoPage(this));
      } else if (path == robotoMonoFontPath) {
        // Note: `return await` needed due to
        // https://github.com/dart-lang/sdk/issues/39204
        return await respond(request, RobotoMonoPage(this));
      } else if (path == '/' ||
          decodedPath == migrationInfo!.includedRoot ||
          decodedPath ==
              '${migrationInfo!.includedRoot}${pathMapper!.separator}') {
        // Note: `return await` needed due to
        // https://github.com/dart-lang/sdk/issues/39204
        return await respond(request, IndexFilePage(this));
      }

      var unitInfo = unitInfoMap[decodedPath];
      if (unitInfo != null) {
        if (uri.queryParameters.containsKey('inline')) {
          // Note: `return await` needed due to
          // https://github.com/dart-lang/sdk/issues/39204
          return await respond(request, DartFilePage(this, unitInfo));
        } else if (uri.queryParameters.containsKey('region')) {
          // Note: `return await` needed due to
          // https://github.com/dart-lang/sdk/issues/39204
          return await respond(request, RegionPage(this, unitInfo));
        } else {
          // Note: `return await` needed due to
          // https://github.com/dart-lang/sdk/issues/39204
          return await respond(request, IndexFilePage(this));
        }
      }
      // Note: `return await` needed due to
      // https://github.com/dart-lang/sdk/issues/39204
      return await respond(
          request, createUnknownPage(path), HttpStatus.notFound);
    } catch (exception, stackTrace) {
      _respondInternalError(request, path, exception, stackTrace);
    }
  }

  @override
  Future<void> handlePostRequest(HttpRequest request) async {
    var uri = request.uri;
    var path = uri.path;
    try {
      // All POST requests must be authorized.
      if (!_isAuthorized(request)) {
        return _respondUnauthorized(request);
      }
      if (path == applyMigrationPath) {
        var navigationTree =
            ((await requestBodyJson(request))['navigationTree'] as List)
                .map((encoded) => NavigationTreeNode.fromJson(encoded));
        performApply(navigationTree);

        respondOk(request);
        return;
      } else if (path == rerunMigrationPath) {
        await rerunMigration();

        if (migrationState!.hasErrors) {
          return await respondJson(
              request,
              {
                'success': false,
                'errors': migrationState!.analysisResult!.toJson(),
              },
              HttpStatus.ok);
        } else {
          respondOk(request);
        }
        return;
      } else if (path == applyHintPath) {
        final hintAction = HintAction.fromJson(await requestBodyJson(request));
        await performHintAction(hintAction);
        respondOk(request);
        return;
      } else if (uri.queryParameters.containsKey('replacement')) {
        await performEdit(uri);

        respondOk(request);
        return;
      }
    } catch (exception, stackTrace) {
      _respondInternalError(request, path, exception, stackTrace);
    }
  }

  /// Perform the migration.
  void performApply(Iterable<NavigationTreeNode> navigationTree) {
    if (migrationState!.hasBeenApplied) {
      throw StateError(
          'It looks like this migration has already been applied. Try'
          ' restarting the migration tool if this is not the case.');
    }

    final edits = migrationState!.listener!.sourceChange.edits;

    // Perform a full check that no files have changed before touching the disk.
    for (final fileEdit in edits) {
      final file = pathMapper!.provider.getFile(fileEdit.file);
      if (!file.path.endsWith('.dart')) {
        continue;
      }
      var unitInfo = unitInfoMap[file.path];
      if (unitInfo == null) {
        // No disk content was recorded for this path at the time migration was
        // performed.  This usually happens because the file is an unreferenced
        // part (and therefore it didn't contribute to the migration at all). So
        // just skip this file.
        continue;
      }
      var code = file.exists ? file.readAsStringSync() : '';
      if (!unitInfo.hadDiskContent(code)) {
        throw StateError('Cannot apply migration. Files on disk do not match'
            ' the expected pre-migration state. Press the "rerun from sources"'
            ' button and then try again. (Changed file path is ${file.path})');
      }
    }

    // Eagerly mark the migration applied. If this throws, we cannot go back.
    migrationState!.markApplied();
    IncrementalPlan(migrationInfo, unitInfoMap, pathMapper, edits,
            navigationTree, logger)
        .apply();
    applyHook();
  }

  /// Perform the edit indicated by the [uri].
  Future<void> performEdit(Uri uri) async {
    //
    // Update the code on disk.
    //
    var params = uri.queryParameters;
    var path = pathMapper!.reverseMap(uri);
    var offset = int.parse(params['offset']!);
    var end = int.parse(params['end']!);
    var replacement = params['replacement']!;
    var file = pathMapper!.provider.getFile(path);
    var diskContent = file.readAsStringSync();
    if (!unitInfoMap[path]!.hadDiskContent(diskContent)) {
      throw StateError('Cannot perform edit. This file has been changed since'
          ' last migration run. Press the "rerun from sources" button and then'
          ' try again. (Changed file path is ${file.path})');
    }
    final unitInfo = unitInfoMap[path]!;
    final diskMapper = unitInfo.diskChangesOffsetMapper;
    final diskOffsetStart = diskMapper.map(offset);
    final diskOffsetEnd = diskMapper.map(end);
    if (diskOffsetStart == null || diskOffsetEnd == null) {
      throw StateError('Cannot perform edit. Relevant code has been deleted by'
          ' a previous hint action. Rerun the migration and try again.');
    }
    unitInfo.handleSourceEdit(SourceEdit(offset, end - offset, replacement));
    migrationState!.needsRerun = true;
    var newContent =
        diskContent.replaceRange(diskOffsetStart, diskOffsetEnd, replacement);
    file.writeAsStringSync(newContent);
    unitInfo.diskContent = newContent;
  }

  /// Perform the hint edit indicated by the [hintAction].
  Future<void> performHintAction(HintAction hintAction) async {
    final node = migrationState!.nodeMapper.nodeForId(hintAction.nodeId)!;
    final edits = node.hintActions[hintAction.kind];
    if (edits == null) {
      throw StateError('This edit was not available to perform.');
    }
    //
    // Update the code on disk.
    //
    var path = node.codeReference!.path;
    var file = pathMapper!.provider.getFile(path);
    var diskContent = file.readAsStringSync();
    if (!unitInfoMap[path]!.hadDiskContent(diskContent)) {
      throw StateError('Cannot perform edit. This file has been changed since'
          ' last migration run. Press the "rerun from sources" button and then'
          ' try again. (Changed file path is ${file.path})');
    }
    final unitInfo = unitInfoMap[path]!;
    final diskMapper = unitInfo.diskChangesOffsetMapper;
    var newContent = diskContent;
    migrationState!.needsRerun = true;
    for (final entry in edits.entries) {
      final offset = entry.key!;
      final edits = entry.value;
      final diskOffset = diskMapper.map(offset);
      if (diskOffset == null) {
        throw StateError(
            'Cannot perform edit. Relevant code has been deleted by'
            ' a previous hint action. Rerun the migration and try again.');
      }
      final unmappedSourceEdit = edits.toSourceEdit(offset);
      final diskSourceEdit = edits.toSourceEdit(diskMapper.map(offset)!);
      unitInfo.handleSourceEdit(unmappedSourceEdit);
      newContent = diskSourceEdit.apply(newContent);
    }
    file.writeAsStringSync(newContent);
    unitInfo.diskContent = newContent;
  }

  Future<Map<String, Object?>> requestBodyJson(HttpRequest request) async =>
      (await request
          .map((entry) => entry.map((i) => i.toInt()).toList())
          .transform<String>(Utf8Decoder())
          .transform(JsonDecoder())
          .single) as Map<String, Object?>;

  Future<void> rerunMigration() async {
    migrationState = await rerunFunction();
    if (!migrationState!.hasErrors) {
      reset();
    }
  }

  void reset() {
    unitInfoMap.clear();
    var unitInfos = migrationInfo!.units!;
    var provider = pathMapper!.provider;
    for (var unit in unitInfos) {
      unitInfoMap[unit.path] = unit;
    }
    for (var unit in migrationInfo!.unitMap.values) {
      if (!unitInfos.contains(unit)) {
        if (unit.content == null) {
          try {
            unit.content = provider.getFile(unit.path!).readAsStringSync();
          } catch (_) {
            // If we can't read the content of the file, then skip it.
            continue;
          }
        }
        unitInfoMap[unit.path] = unit;
      }
    }
  }

  @override
  Future<void> respond(HttpRequest request, Page page,
      [int code = HttpStatus.ok]) async {
    if (page is PreviewPage && page.requiresAuth) {
      if (!_isAuthorized(request)) {
        return _respondUnauthorized(request);
      }
    }
    var response = request.response;
    response.statusCode = code;
    if (page is HighlightCssPage) {
      response.headers.contentType =
          ContentType('text', 'css', charset: 'utf-8');
    } else if (page is HighlightJSPage) {
      response.headers.contentType =
          ContentType('application', 'javascript', charset: 'utf-8');
    } else if (page is DartLogoPage) {
      response.headers.contentType = ContentType('image', 'png');
    } else if (page is MaterialIconsPage ||
        page is RobotoPage ||
        page is RobotoMonoPage) {
      response.headers.contentType = ContentType('font', 'ttf');
    } else {
      response.headers.contentType = ContentType.html;
    }
    response.write(await page.generate(request.uri.queryParameters));
    response.close();
  }

  /// Returns whether [request] is an authorized request.
  bool _isAuthorized(HttpRequest request) {
    var authToken = request.uri.queryParameters['authToken'];
    return authToken == serviceAuthToken;
  }

  Future<void> _respondInternalError(HttpRequest request, String path,
      dynamic exception, StackTrace stackTrace) async {
    try {
      if (request.headers.contentType!.subType == 'json') {
        return await respondJson(
            request,
            {
              'success': false,
              'exception': exception.toString(),
              'stackTrace': stackTrace.toString(),
            },
            HttpStatus.internalServerError);
      }
      await respond(
          request,
          createExceptionPageWithPath(path, '$exception', stackTrace),
          HttpStatus.internalServerError);
    } catch (exception, stackTrace) {
      var response = request.response;
      response.statusCode = HttpStatus.internalServerError;
      response.headers.contentType = ContentType.text;
      response.write('$exception\n\n$stackTrace');
      response.close();
    }
  }

  /// Responds with a 401 Unauthorized response.
  Future<void> _respondUnauthorized(HttpRequest request) async {
    var page = createUnauthorizedPage(request.uri.path);
    var response = request.response;
    response
      ..statusCode = HttpStatus.unauthorized
      ..headers.contentType = ContentType.html
      ..write(await page.generate(request.uri.queryParameters))
      ..close();
  }
}
