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

// @dart = 2.9

// Do not add package imports to this file.
import 'dart:convert'; // ignore: dart_convert_import.
import 'dart:io'; // ignore: dart_io_import.

/// Executes the required flutter tasks for a desktop build.
Future<void> main(List<String> arguments) async {
  final String targetPlatform = arguments[0];
  final String buildMode = arguments[1].toLowerCase();

  final String dartDefines = Platform.environment['DART_DEFINES'];
  final bool dartObfuscation = Platform.environment['DART_OBFUSCATION'] == 'true';
  final String extraFrontEndOptions = Platform.environment['EXTRA_FRONT_END_OPTIONS'];
  final String extraGenSnapshotOptions = Platform.environment['EXTRA_GEN_SNAPSHOT_OPTIONS'];
  final String flutterEngine = Platform.environment['FLUTTER_ENGINE'];
  final String flutterRoot = Platform.environment['FLUTTER_ROOT'];
  final String flutterTarget = Platform.environment['FLUTTER_TARGET']
    ?? pathJoin(<String>['lib', 'main.dart']);
  final String codeSizeDirectory = Platform.environment['CODE_SIZE_DIRECTORY'];
  final String localEngine = Platform.environment['LOCAL_ENGINE'];
  final String projectDirectory = Platform.environment['PROJECT_DIR'];
  final String splitDebugInfo = Platform.environment['SPLIT_DEBUG_INFO'];
  final String bundleSkSLPath = Platform.environment['BUNDLE_SKSL_PATH'];
  final bool trackWidgetCreation = Platform.environment['TRACK_WIDGET_CREATION'] == 'true';
  final bool treeShakeIcons = Platform.environment['TREE_SHAKE_ICONS'] == 'true';
  final bool verbose = Platform.environment['VERBOSE_SCRIPT_LOGGING'] == 'true';
  final bool prefixedErrors = Platform.environment['PREFIXED_ERROR_LOGGING'] == 'true';

  Directory.current = projectDirectory;

  if (localEngine != null && !localEngine.contains(buildMode)) {
    stderr.write('''
ERROR: Requested build with Flutter local engine at '$localEngine'
This engine is not compatible with FLUTTER_BUILD_MODE: '$buildMode'.
You can fix this by updating the LOCAL_ENGINE environment variable, or
by running:
  flutter build <platform> --local-engine=host_$buildMode
or
  flutter build <platform> --local-engine=host_${buildMode}_unopt
========================================================================
''');
    exit(1);
  }
  final String flutterExecutable = pathJoin(<String>[
    flutterRoot,
    'bin',
    if (Platform.isWindows)
      'flutter.bat'
    else
      'flutter'
  ]);
  final String bundlePlatform = targetPlatform == 'windows-x64' ? 'windows' : 'linux';
  final String target = '${buildMode}_bundle_${bundlePlatform}_assets';

  final Process assembleProcess = await Process.start(
    flutterExecutable,
    <String>[
      if (verbose)
        '--verbose',
      if (prefixedErrors)
        '--prefixed-errors',
      if (flutterEngine != null) '--local-engine-src-path=$flutterEngine',
      if (localEngine != null) '--local-engine=$localEngine',
      'assemble',
      '--output=build',
      '-dTargetPlatform=$targetPlatform',
      '-dTrackWidgetCreation=$trackWidgetCreation',
      '-dBuildMode=$buildMode',
      '-dTargetFile=$flutterTarget',
      '-dTreeShakeIcons="$treeShakeIcons"',
      '-dDartObfuscation=$dartObfuscation',
      if (bundleSkSLPath != null)
        '-iBundleSkSLPath=$bundleSkSLPath',
      if (codeSizeDirectory != null)
        '-dCodeSizeDirectory=$codeSizeDirectory',
      if (splitDebugInfo != null)
        '-dSplitDebugInfo=$splitDebugInfo',
      if (dartDefines != null)
        '--DartDefines=$dartDefines',
      if (extraGenSnapshotOptions != null)
        '--ExtraGenSnapshotOptions=$extraGenSnapshotOptions',
      if (extraFrontEndOptions != null)
        '--ExtraFrontEndOptions=$extraFrontEndOptions',
      target,
    ],
  );
  assembleProcess.stdout
    .transform(utf8.decoder)
    .transform(const LineSplitter())
    .listen(stdout.writeln);
  assembleProcess.stderr
    .transform(utf8.decoder)
    .transform(const LineSplitter())
    .listen(stderr.writeln);

  if (await assembleProcess.exitCode != 0) {
    exit(1);
  }
}

/// Perform a simple path join on the segments based on the current platform.
///
/// Does not normalize paths that have repeated separators.
String pathJoin(List<String> segments) {
  final String separator = Platform.isWindows ? r'\' : '/';
  return segments.join(separator);
}
