// Copyright 2020 The Dart Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// @dart = 2.9

// Note: this is a copy from flutter tools, updated to work with dwds tests

import 'dart:io';

import 'package:dwds/dwds.dart';
import 'package:file/file.dart';
import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';
import 'package:path/path.dart' as p;

import 'asset_server.dart';
import 'bootstrap.dart';
import 'frontend_server_client.dart';
import 'utilities.dart';

final String dartWebSdkPath = p.join(dartSdkPath, 'lib', 'dev_compiler');

class WebDevFS {
  WebDevFS({
    this.fileSystem,
    this.hostname,
    this.port,
    this.packageConfigPath,
    this.root,
    this.urlTunneller,
    this.soundNullSafety,
  });

  final FileSystem fileSystem;
  TestAssetServer assetServer;
  final String hostname;
  final int port;
  final String packageConfigPath;
  final String root;
  final UrlEncoder urlTunneller;
  final bool soundNullSafety;
  Directory _savedCurrentDirectory;
  List<Uri> sources;
  PackageConfig _packageConfig;

  Future<Uri> create() async {
    _savedCurrentDirectory = fileSystem.currentDirectory;
    // package_config.json is located in <project directory>/.dart_tool/package_config
    var projectDirectory = p.dirname(p.dirname(packageConfigPath));

    fileSystem.currentDirectory = projectDirectory;

    _packageConfig = await loadPackageConfigUri(Uri.file(packageConfigPath),
        loader: (Uri uri) => fileSystem.file(uri).readAsBytes());

    assetServer = await TestAssetServer.start(
        fileSystem, root, hostname, port, urlTunneller, _packageConfig);
    return Uri.parse('http://$hostname:$port');
  }

  Future<void> dispose() {
    fileSystem.currentDirectory = _savedCurrentDirectory;
    return assetServer?.close();
  }

  Future<UpdateFSReport> update({
    String mainPath,
    String dillOutputPath,
    @required @required @required @required @required ResidentCompiler generator,
    List<Uri> invalidatedFiles,
  }) async {
    assert(generator != null);
    var outputDirectoryPath = fileSystem.file(mainPath).parent.path;
    var entryPoint = mainPath;

    assetServer.writeFile(
      '/main.dart.js',
      generateBootstrapScript(
        requireUrl: _filePathToUriFragment(requireJS.path),
        mapperUrl: _filePathToUriFragment(stackTraceMapper.path),
        entrypoint: entryPoint,
      ),
    );
    assetServer.writeFile(
      '/main_module.bootstrap.js',
      generateMainModule(
        entrypoint: entryPoint,
      ),
    );

    assetServer.writeFile('/main_module.digests', '{}');
    var sdk = soundNullSafety ? dartSdkSound : dartSdk;
    var sdkSourceMap =
        soundNullSafety ? dartSdkSourcemapSound : dartSdkSourcemap;
    assetServer.writeFile('/dart_sdk.js', sdk.readAsStringSync());
    assetServer.writeFile('/dart_sdk.js.map', sdkSourceMap.readAsStringSync());

    generator.reset();
    var compilerOutput = await generator.recompile(
        Uri.parse('org-dartlang-app:///$mainPath'), invalidatedFiles,
        outputPath: p.join(dillOutputPath, 'app.dill'),
        packageConfig: _packageConfig);
    if (compilerOutput == null || compilerOutput.errorCount > 0) {
      return UpdateFSReport(success: false);
    }

    // list of sources that needs to be monitored are in [compilerOutput.sources]
    sources = compilerOutput.sources;
    File codeFile;
    File manifestFile;
    File sourcemapFile;
    File metadataFile;
    List<String> modules;
    try {
      var parentDirectory = fileSystem.directory(outputDirectoryPath);
      codeFile =
          parentDirectory.childFile('${compilerOutput.outputFilename}.sources');
      manifestFile =
          parentDirectory.childFile('${compilerOutput.outputFilename}.json');
      sourcemapFile =
          parentDirectory.childFile('${compilerOutput.outputFilename}.map');
      metadataFile = parentDirectory
          .childFile('${compilerOutput.outputFilename}.metadata');
      modules = assetServer.write(
          codeFile, manifestFile, sourcemapFile, metadataFile);
    } on FileSystemException catch (err) {
      throw Exception('Failed to load recompiled sources:\n$err');
    }
    return UpdateFSReport(
      success: true,
      syncedBytes: codeFile.lengthSync(),
      invalidatedSourcesCount: invalidatedFiles.length,
    )..invalidatedModules = modules;
  }

  File get requireJS => fileSystem.file(fileSystem.path.join(
        dartWebSdkPath,
        'kernel',
        'amd',
        'require.js',
      ));

  File get dartSdk => fileSystem.file(fileSystem.path.join(
        dartWebSdkPath,
        'kernel',
        'amd',
        'dart_sdk.js',
      ));

  File get dartSdkSound => fileSystem.file(fileSystem.path.join(
        dartWebSdkPath,
        'kernel',
        'amd',
        'dart_sdk_sound.js',
      ));

  File get dartSdkSourcemap => fileSystem.file(fileSystem.path.join(
        dartWebSdkPath,
        'kernel',
        'amd',
        'dart_sdk.js.map',
      ));

  File get dartSdkSourcemapSound => fileSystem.file(fileSystem.path.join(
        dartWebSdkPath,
        'kernel',
        'amd',
        'dart_sdk_sound.js.map',
      ));

  File get stackTraceMapper => fileSystem.file(fileSystem.path.join(
        dartWebSdkPath,
        'web',
        'dart_stack_trace_mapper.js',
      ));
}

class UpdateFSReport {
  final bool _success;
  final int _invalidatedSourcesCount;
  final int _syncedBytes;

  UpdateFSReport({
    bool success = false,
    int invalidatedSourcesCount = 0,
    int syncedBytes = 0,
  })  : _success = success,
        _invalidatedSourcesCount = invalidatedSourcesCount,
        _syncedBytes = syncedBytes;

  bool get success => _success;
  int get invalidatedSourcesCount => _invalidatedSourcesCount;
  int get syncedBytes => _syncedBytes;

  /// JavaScript modules produced by the incremental compiler in `dartdevc`
  /// mode.
  ///
  /// Only used for JavaScript compilation.
  List<String> invalidatedModules;
}

String _filePathToUriFragment(String path) {
  if (Platform.isWindows) {
    var startWithSlash = path.startsWith('/');
    var partial =
        fileSystem.path.split(path).skip(startWithSlash ? 2 : 1).join('/');
    if (partial.startsWith('/')) {
      return partial;
    }
    return '/$partial';
  }
  return path;
}
