// 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.

import 'dart:convert';
import 'dart:io';

import 'package:async/async.dart';
import 'package:frontend_server_client/frontend_server_client.dart';
import 'package:path/path.dart' as p;
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_packages_handler/shelf_packages_handler.dart';
import 'package:shelf_static/shelf_static.dart';

void main(List<String> args) async {
  try {
    watch.start();
    if (args.isNotEmpty) {
      throw ArgumentError('No command line args are supported');
    }

    _print('compiling the dart sdk');
    var sdkCompileResult = await Process.run(Platform.resolvedExecutable, [
      p.join(sdkDir, 'bin', 'snapshots', 'dartdevc.dart.snapshot'),
      '--multi-root-scheme=org-dartlang-sdk',
      '--modules=amd',
      '--module-name=dart_sdk',
      '--sound-null-safety',
      '-o',
      dartSdkJs,
      p.url.join(sdkDir, sdkKernelPath),
    ]);
    if (sdkCompileResult.exitCode != 0) {
      _print('Failed to compile the dart sdk to JS:\n'
          '${sdkCompileResult.stdout}\n'
          '${sdkCompileResult.stderr}');
      exit(sdkCompileResult.exitCode);
    }

    _print('starting frontend server');
    var client = await DartDevcFrontendServerClient.start(
        'org-dartlang-root:///$app', outputDill,
        fileSystemRoots: [p.current],
        fileSystemScheme: 'org-dartlang-root',
        platformKernel: p.toUri(sdkKernelPath).toString(),
        verbose: true);

    _print('compiling $app');
    await client.compile([]);
    client.accept();
    _print('done compiling $app');

    _print('starting shelf server');
    var cascade = Cascade()
        .add(_clientHandler(client))
        .add(createStaticHandler(p.current))
        .add(createFileHandler(dartSdkJs, url: 'example/app/dart_sdk.js'))
        .add(createFileHandler(
            p.join(sdkDir, 'lib', 'dev_compiler', 'web',
                'dart_stack_trace_mapper.js'),
            url: 'example/app/dart_stack_trace_mapper.js'))
        .add(createFileHandler(
            p.join(sdkDir, 'lib', 'dev_compiler', 'amd', 'require.js'),
            url: 'example/app/require.js'))
        .add(packagesDirHandler());
    final server = await shelf_io.serve(cascade.handler, 'localhost', 8080);
    _print('server ready');

    // The file we will be editing in the repl
    var appFile = File(app);
    var originalContent = await appFile.readAsString();
    var appLines = const LineSplitter().convert(originalContent);
    var getterText = 'String get message =>';
    var messageLine =
        appLines.indexWhere((line) => line.startsWith(getterText));

    var stdinQueue = StreamQueue(
        stdin.transform(utf8.decoder).transform(const LineSplitter()));
    _prompt();
    while (await stdinQueue.hasNext) {
      var newMessage = await stdinQueue.next;
      if (newMessage == 'quit') {
        await server.close();
        await stdinQueue.cancel();
        break;
      } else if (newMessage == 'reset') {
        print('resetting');
        client.reset();
        _print('restoring $app');
        await appFile.writeAsString(originalContent);
      } else {
        _print('editing $app');
        appLines[messageLine] = '$getterText "$newMessage";';
        var newContent = appLines.join('\n');
        await appFile.writeAsString(newContent);

        _print('recompiling $app with edits');
        var result =
            await client.compile([Uri.parse('org-dartlang-root:///$app')]);
        if (result.errorCount > 0) {
          print('Compile errors: \n${result.compilerOutputLines.join('\n')}');
          await client.reject();
        } else {
          _print('Recompile succeeded for $app');
          client.accept();
          // TODO: support hot restart
          print('reload app to see the new message');
        }
      }

      _prompt();
    }

    _print('restoring $app');
    await appFile.writeAsString(originalContent);
    _print('exiting');
    await client.shutdown();
  } finally {
    Directory(p.join('.dart_tool', 'out')).deleteSync(recursive: true);
  }
}

Handler _clientHandler(DartDevcFrontendServerClient client) {
  return (Request request) {
    var path = request.url.path;
    var packagesIndex = path.indexOf('/packages/');
    if (packagesIndex > 0) {
      path = request.url.path.substring(packagesIndex);
    } else {
      path = request.url.path;
    }
    if (!path.startsWith('/')) path = '/$path';
    if (path.endsWith('.dart.js') && path != '/example/app/main.dart.js') {
      path = path.replaceFirst('.dart.js', '.dart.lib.js', path.length - 8);
    }
    var assetBytes = client.assetBytes(path);
    if (assetBytes == null) return Response.notFound('path not found');
    return Response.ok(assetBytes,
        headers: {HttpHeaders.contentTypeHeader: 'application/javascript'});
  };
}

void _print(String message) {
  print('${watch.elapsed}: $message');
}

void _prompt() => stdout.write(
    'Enter a new message to print and recompile, or type `quit` to exit:');

final app = 'example/app/main.dart';
final dartSdkJs = p.join('.dart_tool', 'out', 'dart_sdk.js');
final outputDill = p.join('.dart_tool', 'out', 'example_app.dill');
final sdkDir = p.dirname(p.dirname(Platform.resolvedExecutable));
final sdkKernelPath = p.join(sdkDir, 'lib', '_internal', 'ddc_platform.dill');
final watch = Stopwatch();
