// Copyright 2013 The Flutter 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:io';

import 'package:litetest/litetest.dart';
import 'package:path/path.dart' as path;

Future<void> main(List<String> args) async {
  if (args.length != 3) {
    stderr.writeln('The first argument must be the path to the build output.');
    stderr.writeln('The second argument must be the path to the frontend server dill.');
    stderr.writeln('The third argument must be the path to the flutter_patched_sdk');
    exit(-1);
  }

  final String dart = Platform.resolvedExecutable;
  final String dartaotruntime = path.join(path.dirname(Platform.resolvedExecutable), 'dartaotruntime');
  final String buildDir = args[0];
  final String frontendServer = args[1];
  final String sdkRoot = args[2];
  final String basePath = path.canonicalize(path.join(path.dirname(Platform.script.toFilePath()), '..'));
  final String fixtures = path.join(basePath, 'test', 'fixtures');
  final String mainDart = path.join(fixtures, 'lib', 'main.dart');
  final String packageConfig = path.join(fixtures, '.dart_tool', 'package_config.json');
  final String regularDill = path.join(fixtures, 'toString.dill');
  final String transformedDill = path.join(fixtures, 'toStringTransformed.dill');

  void checkProcessResult(ProcessResult result) {
    if (result.exitCode != 0) {
      stdout.writeln(result.stdout);
      stderr.writeln(result.stderr);
    }
    expect(result.exitCode, 0);
  }

  test('Without flag', () {
    checkProcessResult(Process.runSync(dartaotruntime, <String>[
      frontendServer,
      '--sdk-root=$sdkRoot',
      '--target=flutter',
      '--packages=$packageConfig',
      '--output-dill=$regularDill',
      mainDart,
    ]));
    final ProcessResult runResult = Process.runSync(dart, <String>[regularDill]);
    checkProcessResult(runResult);
    String paintString = '"Paint.toString":"Paint(Color(0xffffffff))"';
    if (buildDir.contains('release')) {
      paintString = '"Paint.toString":"Instance of \'Paint\'"';
    }

    final String expectedStdout = '{$paintString,'
      '"Brightness.toString":"Brightness.dark",'
      '"Foo.toString":"I am a Foo",'
      '"Keep.toString":"I am a Keep"}';
    final String actualStdout = (runResult.stdout as String).trim();
    expect(actualStdout, equals(expectedStdout));
  });

  test('With flag', () {
    checkProcessResult(Process.runSync(dartaotruntime, <String>[
      frontendServer,
      '--sdk-root=$sdkRoot',
      '--target=flutter',
      '--packages=$packageConfig',
      '--output-dill=$transformedDill',
      '--delete-tostring-package-uri', 'dart:ui',
      '--delete-tostring-package-uri', 'package:flutter_frontend_fixtures',
      mainDart,
    ]));
    final ProcessResult runResult = Process.runSync(dart, <String>[transformedDill]);
    checkProcessResult(runResult);

    const String expectedStdout = '{"Paint.toString":"Instance of \'Paint\'",'
      '"Brightness.toString":"Brightness.dark",'
      '"Foo.toString":"Instance of \'Foo\'",'
      '"Keep.toString":"I am a Keep"}';
    final String actualStdout = (runResult.stdout as String).trim();
    expect(actualStdout, equals(expectedStdout));
  });
}
