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

    if (migratedFiles.isNotEmpty) {
      var migratedCount = migratedFiles.length;
      if (migratedCount <= 20) {
        var s = migratedCount > 1 ? 's' : '';
        logger.stdout('Migrated $migratedCount file$s:');
        for (var path in migratedFiles) {
          logger.stdout('    $path');
        }
      } else {
        logger.stdout('Migrated $migratedCount files.');
      }
    }
    if (newlyOptedOutFiles.isNotEmpty) {
      var newlyOptedOutCount = newlyOptedOutFiles.length;
      if (newlyOptedOutCount <= 20) {
        var s = newlyOptedOutCount > 1 ? 's' : '';
        logger.stdout(
            'Opted $newlyOptedOutCount file$s out of null safety with a new '
            'Dart language version comment:');
        for (var path in newlyOptedOutFiles) {
          logger.stdout('    $path');
        }
      } else {
        logger.stdout(
            'Opted $newlyOptedOutCount files out of null safety with a new '
            'Dart language version comment.');
      }
    }
    if (keptOptedOutFiles.isNotEmpty) {
      var keptOptedOutCount = keptOptedOutFiles.length;
      if (keptOptedOutCount <= 20) {
        var s = keptOptedOutCount > 1 ? 's' : '';
        logger
            .stdout('Kept $keptOptedOutCount file$s opted out of null safety:');
        for (var path in keptOptedOutFiles) {
          logger.stdout('    $path');
        }
      } else {
        logger.stdout('Kept $keptOptedOutCount files out of null safety.');
      }
    }
  }

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

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

    var index = 0;

    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) {
      // Comment.
      if (index == length) {
        // [code] consists _only_ of one comment line.
        return '$code$newline$newline// @dart=2.9$newline';
      }
      line = getLine();
      lineStart = line.indexOf(_nonWhitespaceChar);
      while (lineStart >= 0 &&
          line.length > lineStart + 1 &&
          line.codeUnitAt(lineStart) == $slash &&
          line.codeUnitAt(lineStart + 1) == $slash) {
        // Another comment line.
        line = getLine();
        if (index == length) {
          // [code] consists _only_ of this block comment.
          return '$code$newline$newline// @dart=2.9$newline';
        }
        lineStart = line.indexOf(_nonWhitespaceChar);
      }
      // [index] points to the start of [line], which is the first
      // non-comment line following the first comment.
      return '${code.substring(0, index)}$newline// @dart=2.9$newline$newline'
          '${code.substring(index)}';
    } 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 code = file.exists ? file.readAsStringSync() : '';
      if (!unitInfoMap[file.path].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();
  }
}
