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

import 'package:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/build_system/targets/icon_tree_shaker.dart';
import 'package:flutter_tools/src/devfs.dart';

import '../../../src/common.dart';
import '../../../src/fake_process_manager.dart';
import '../../../src/fakes.dart';

const List<int> _kTtfHeaderBytes = <int>[0, 1, 0, 0, 0, 15, 0, 128, 0, 3, 0, 112];

const String inputPath = '/input/fonts/MaterialIcons-Regular.otf';
const String outputPath = '/output/fonts/MaterialIcons-Regular.otf';
const String relativePath = 'fonts/MaterialIcons-Regular.otf';

final RegExp whitespace = RegExp(r'\s+');

void main() {
  late BufferLogger logger;
  late MemoryFileSystem fileSystem;
  late FakeProcessManager processManager;
  late Artifacts artifacts;
  late DevFSStringContent fontManifestContent;

  late String dartPath;
  late String constFinderPath;
  late String fontSubsetPath;
  late List<String> fontSubsetArgs;

  List<String> getConstFinderArgs(String appDillPath) => <String>[
    dartPath,
    '--disable-dart-dev',
    constFinderPath,
    '--kernel-file', appDillPath,
    '--class-library-uri', 'package:flutter/src/widgets/icon_data.dart',
    '--class-name', 'IconData',
    '--annotation-class-name', '_StaticIconProvider',
    '--annotation-class-library-uri', 'package:flutter/src/widgets/icon_data.dart',
  ];

  void addConstFinderInvocation(
    String appDillPath, {
    int exitCode = 0,
    String stdout = '',
    String stderr = '',
  }) {
    processManager.addCommand(FakeCommand(
      command: getConstFinderArgs(appDillPath),
      exitCode: exitCode,
      stdout: stdout,
      stderr: stderr,
    ));
  }

  void resetFontSubsetInvocation({
    int exitCode = 0,
    String stdout = '',
    String stderr = '',
    required CompleterIOSink stdinSink,
  }) {
    stdinSink.clear();
    processManager.addCommand(FakeCommand(
      command: fontSubsetArgs,
      exitCode: exitCode,
      stdout: stdout,
      stderr: stderr,
      stdin: stdinSink,
    ));
  }

  setUp(() {
    processManager = FakeProcessManager.empty();
    fontManifestContent = DevFSStringContent(validFontManifestJson);
    artifacts = Artifacts.test();
    fileSystem = MemoryFileSystem.test();
    logger = BufferLogger.test();
    dartPath = artifacts.getArtifactPath(Artifact.engineDartBinary);
    constFinderPath = artifacts.getArtifactPath(Artifact.constFinder);
    fontSubsetPath = artifacts.getArtifactPath(Artifact.fontSubset);

    fontSubsetArgs = <String>[
      fontSubsetPath,
      outputPath,
      inputPath,
    ];

    fileSystem.file(constFinderPath).createSync(recursive: true);
    fileSystem.file(dartPath).createSync(recursive: true);
    fileSystem.file(fontSubsetPath).createSync(recursive: true);
    fileSystem.file(inputPath)
      ..createSync(recursive: true)
      ..writeAsBytesSync(_kTtfHeaderBytes);
  });

  Environment createEnvironment(Map<String, String> defines) {
    return Environment.test(
      fileSystem.directory('/icon_test')..createSync(recursive: true),
      defines: defines,
      artifacts: artifacts,
      processManager: FakeProcessManager.any(),
      fileSystem: fileSystem,
      logger: BufferLogger.test(),
    );
  }

  testWithoutContext('Prints error in debug mode environment', () async {
    final Environment environment = createEnvironment(<String, String>{
      kIconTreeShakerFlag: 'true',
      kBuildMode: 'debug',
    });

    final IconTreeShaker iconTreeShaker = IconTreeShaker(
      environment,
      fontManifestContent,
      logger: logger,
      processManager: processManager,
      fileSystem: fileSystem,
      artifacts: artifacts,
      targetPlatform: TargetPlatform.android,
    );

    expect(
      logger.errorText,
      'Font subsetting is not supported in debug mode. The --tree-shake-icons'
      ' flag will be ignored.\n',
    );
    expect(iconTreeShaker.enabled, false);

    final bool subsets = await iconTreeShaker.subsetFont(
      input: fileSystem.file(inputPath),
      outputPath: outputPath,
      relativePath: relativePath,
    );
    expect(subsets, false);
    expect(processManager, hasNoRemainingExpectations);
  });

  testWithoutContext('Does not get enabled without font manifest', () {
    final Environment environment = createEnvironment(<String, String>{
      kIconTreeShakerFlag: 'true',
      kBuildMode: 'release',
    });

    final IconTreeShaker iconTreeShaker = IconTreeShaker(
      environment,
      null,
      logger: logger,
      processManager: processManager,
      fileSystem: fileSystem,
      artifacts: artifacts,
      targetPlatform: TargetPlatform.android,
    );

    expect(
      logger.errorText,
      isEmpty,
    );
    expect(iconTreeShaker.enabled, false);
    expect(processManager, hasNoRemainingExpectations);
  });

  testWithoutContext('Gets enabled', () {
    final Environment environment = createEnvironment(<String, String>{
      kIconTreeShakerFlag: 'true',
      kBuildMode: 'release',
    });

    final IconTreeShaker iconTreeShaker = IconTreeShaker(
      environment,
      fontManifestContent,
      logger: logger,
      processManager: processManager,
      fileSystem: fileSystem,
      artifacts: artifacts,
      targetPlatform: TargetPlatform.android,
    );

    expect(
      logger.errorText,
      isEmpty,
    );
    expect(iconTreeShaker.enabled, true);
    expect(processManager, hasNoRemainingExpectations);
  });

  test('No app.dill throws exception', () async {
    final Environment environment = createEnvironment(<String, String>{
      kIconTreeShakerFlag: 'true',
      kBuildMode: 'release',
    });

    final IconTreeShaker iconTreeShaker = IconTreeShaker(
      environment,
      fontManifestContent,
      logger: logger,
      processManager: processManager,
      fileSystem: fileSystem,
      artifacts: artifacts,
      targetPlatform: TargetPlatform.android,
    );

    expect(
      () async => iconTreeShaker.subsetFont(
        input: fileSystem.file(inputPath),
        outputPath: outputPath,
        relativePath: relativePath,
      ),
      throwsA(isA<IconTreeShakerException>()),
    );
    expect(processManager, hasNoRemainingExpectations);
  });

  testWithoutContext('Can subset a font', () async {
    final Environment environment = createEnvironment(<String, String>{
      kIconTreeShakerFlag: 'true',
      kBuildMode: 'release',
    });
    final File appDill = environment.buildDir.childFile('app.dill')
      ..createSync(recursive: true);

    final IconTreeShaker iconTreeShaker = IconTreeShaker(
      environment,
      fontManifestContent,
      logger: logger,
      processManager: processManager,
      fileSystem: fileSystem,
      artifacts: artifacts,
      targetPlatform: TargetPlatform.android,
    );
    final CompleterIOSink stdinSink = CompleterIOSink();
    addConstFinderInvocation(appDill.path, stdout: validConstFinderResult);
    resetFontSubsetInvocation(stdinSink: stdinSink);
    // Font starts out 2500 bytes long
    final File inputFont = fileSystem.file(inputPath)
        ..writeAsBytesSync(List<int>.filled(2500, 0));
    // after subsetting, font is 1200 bytes long
    fileSystem.file(outputPath)
        ..createSync(recursive: true)
        ..writeAsBytesSync(List<int>.filled(1200, 0));
    bool subsetted = await iconTreeShaker.subsetFont(
      input: inputFont,
      outputPath: outputPath,
      relativePath: relativePath,
    );
    expect(stdinSink.getAndClear(), '59470\n');
    resetFontSubsetInvocation(stdinSink: stdinSink);

    expect(subsetted, true);
    subsetted = await iconTreeShaker.subsetFont(
      input: fileSystem.file(inputPath),
      outputPath: outputPath,
      relativePath: relativePath,
    );
    expect(subsetted, true);
    expect(stdinSink.getAndClear(), '59470\n');
    expect(processManager, hasNoRemainingExpectations);
    expect(
      logger.statusText,
      contains('Font asset "MaterialIcons-Regular.otf" was tree-shaken, reducing it from 2500 to 1200 bytes (52.0% reduction). Tree-shaking can be disabled by providing the --no-tree-shake-icons flag when building your app.'),
    );
  });

  testWithoutContext('Does not subset a non-supported font', () async {
    final Environment environment = createEnvironment(<String, String>{
      kIconTreeShakerFlag: 'true',
      kBuildMode: 'release',
    });
    final File appDill = environment.buildDir.childFile('app.dill')
      ..createSync(recursive: true);

    final IconTreeShaker iconTreeShaker = IconTreeShaker(
      environment,
      fontManifestContent,
      logger: logger,
      processManager: processManager,
      fileSystem: fileSystem,
      artifacts: artifacts,
      targetPlatform: TargetPlatform.android,
    );

    final CompleterIOSink stdinSink = CompleterIOSink();
    addConstFinderInvocation(appDill.path, stdout: validConstFinderResult);
    resetFontSubsetInvocation(stdinSink: stdinSink);

    final File notAFont = fileSystem.file('input/foo/bar.txt')
      ..createSync(recursive: true)
      ..writeAsStringSync('I could not think of a better string');
    final bool subsetted = await iconTreeShaker.subsetFont(
      input: notAFont,
      outputPath: outputPath,
      relativePath: relativePath,
    );
    expect(subsetted, false);
  });

  testWithoutContext('Does not subset an invalid ttf font', () async {
    final Environment environment = createEnvironment(<String, String>{
      kIconTreeShakerFlag: 'true',
      kBuildMode: 'release',
    });
    final File appDill = environment.buildDir.childFile('app.dill')
      ..createSync(recursive: true);

    final IconTreeShaker iconTreeShaker = IconTreeShaker(
      environment,
      fontManifestContent,
      logger: logger,
      processManager: processManager,
      fileSystem: fileSystem,
      artifacts: artifacts,
      targetPlatform: TargetPlatform.android,
    );

    final CompleterIOSink stdinSink = CompleterIOSink();
    addConstFinderInvocation(appDill.path, stdout: validConstFinderResult);
    resetFontSubsetInvocation(stdinSink: stdinSink);

    final File notAFont = fileSystem.file(inputPath)
      ..writeAsBytesSync(<int>[0, 1, 2]);
    final bool subsetted = await iconTreeShaker.subsetFont(
      input: notAFont,
      outputPath: outputPath,
      relativePath: relativePath,
    );

    expect(subsetted, false);
  });

  for (final TargetPlatform platform in <TargetPlatform>[TargetPlatform.android_arm, TargetPlatform.web_javascript]) {
    testWithoutContext('Non-constant instances $platform', () async {
      final Environment environment = createEnvironment(<String, String>{
        kIconTreeShakerFlag: 'true',
        kBuildMode: 'release',
      });
      final File appDill = environment.buildDir.childFile('app.dill')
        ..createSync(recursive: true);

      final IconTreeShaker iconTreeShaker = IconTreeShaker(
        environment,
        fontManifestContent,
        logger: logger,
        processManager: processManager,
        fileSystem: fileSystem,
        artifacts: artifacts,
        targetPlatform: platform,
      );

      addConstFinderInvocation(appDill.path, stdout: constFinderResultWithInvalid);

      await expectLater(
        () => iconTreeShaker.subsetFont(
          input: fileSystem.file(inputPath),
          outputPath: outputPath,
          relativePath: relativePath,
        ),
        throwsToolExit(
          message:
            'Avoid non-constant invocations of IconData or try to build'
            ' again with --no-tree-shake-icons.',
        ),
      );
      expect(processManager, hasNoRemainingExpectations);
    });
  }

  testWithoutContext('Does not add 0x32 for non-web builds', () async {
    final Environment environment = createEnvironment(<String, String>{
      kIconTreeShakerFlag: 'true',
      kBuildMode: 'release',
    });
    final File appDill = environment.buildDir.childFile('app.dill')
      ..createSync(recursive: true);

    final IconTreeShaker iconTreeShaker = IconTreeShaker(
      environment,
      fontManifestContent,
      logger: logger,
      processManager: processManager,
      fileSystem: fileSystem,
      artifacts: artifacts,
      targetPlatform: TargetPlatform.android_arm64,
    );

    addConstFinderInvocation(
      appDill.path,
      // Does not contain space char
      stdout: validConstFinderResult,
    );
    final CompleterIOSink stdinSink = CompleterIOSink();
    resetFontSubsetInvocation(stdinSink: stdinSink);
    expect(processManager.hasRemainingExpectations, isTrue);
    final File inputFont = fileSystem.file(inputPath)
        ..writeAsBytesSync(List<int>.filled(2500, 0));
    fileSystem.file(outputPath)
        ..createSync(recursive: true)
        ..writeAsBytesSync(List<int>.filled(1200, 0));

    final bool result = await iconTreeShaker.subsetFont(
      input: inputFont,
      outputPath: outputPath,
      relativePath: relativePath,
    );

    expect(result, isTrue);
    final List<String> codePoints = stdinSink.getAndClear().trim().split(whitespace);
    expect(codePoints, isNot(contains('optional:32')));

    expect(processManager, hasNoRemainingExpectations);
  });

  testWithoutContext('Ensures 0x32 is included for web builds', () async {
    final Environment environment = createEnvironment(<String, String>{
      kIconTreeShakerFlag: 'true',
      kBuildMode: 'release',
    });
    final File appDill = environment.buildDir.childFile('app.dill')
      ..createSync(recursive: true);

    final IconTreeShaker iconTreeShaker = IconTreeShaker(
      environment,
      fontManifestContent,
      logger: logger,
      processManager: processManager,
      fileSystem: fileSystem,
      artifacts: artifacts,
      targetPlatform: TargetPlatform.web_javascript,
    );

    addConstFinderInvocation(
      appDill.path,
      // Does not contain space char
      stdout: validConstFinderResult,
    );
    final CompleterIOSink stdinSink = CompleterIOSink();
    resetFontSubsetInvocation(stdinSink: stdinSink);
    expect(processManager.hasRemainingExpectations, isTrue);
    final File inputFont = fileSystem.file(inputPath)
        ..writeAsBytesSync(List<int>.filled(2500, 0));
    fileSystem.file(outputPath)
        ..createSync(recursive: true)
        ..writeAsBytesSync(List<int>.filled(1200, 0));

    final bool result = await iconTreeShaker.subsetFont(
      input: inputFont,
      outputPath: outputPath,
      relativePath: relativePath,
    );

    expect(result, isTrue);
    final List<String> codePoints = stdinSink.getAndClear().trim().split(whitespace);
    expect(codePoints, containsAllInOrder(const <String>['59470', 'optional:32']));

    expect(processManager, hasNoRemainingExpectations);
  });

  testWithoutContext('Non-zero font-subset exit code', () async {
    final Environment environment = createEnvironment(<String, String>{
      kIconTreeShakerFlag: 'true',
      kBuildMode: 'release',
    });
    final File appDill = environment.buildDir.childFile('app.dill')
      ..createSync(recursive: true);
    fileSystem.file(inputPath).createSync(recursive: true);

    final IconTreeShaker iconTreeShaker = IconTreeShaker(
      environment,
      fontManifestContent,
      logger: logger,
      processManager: processManager,
      fileSystem: fileSystem,
      artifacts: artifacts,
      targetPlatform: TargetPlatform.android,
    );

    final CompleterIOSink stdinSink = CompleterIOSink();
    addConstFinderInvocation(appDill.path, stdout: validConstFinderResult);
    resetFontSubsetInvocation(exitCode: -1, stdinSink: stdinSink);

    await expectLater(
      () => iconTreeShaker.subsetFont(
        input: fileSystem.file(inputPath),
        outputPath: outputPath,
        relativePath: relativePath,
      ),
      throwsA(isA<IconTreeShakerException>()),
    );
    expect(processManager, hasNoRemainingExpectations);
  });

  testWithoutContext('font-subset throws on write to sdtin', () async {
    final Environment environment = createEnvironment(<String, String>{
      kIconTreeShakerFlag: 'true',
      kBuildMode: 'release',
    });
    final File appDill = environment.buildDir.childFile('app.dill')
      ..createSync(recursive: true);

    final IconTreeShaker iconTreeShaker = IconTreeShaker(
      environment,
      fontManifestContent,
      logger: logger,
      processManager: processManager,
      fileSystem: fileSystem,
      artifacts: artifacts,
      targetPlatform: TargetPlatform.android,
    );

    final CompleterIOSink stdinSink = CompleterIOSink(throwOnAdd: true);
    addConstFinderInvocation(appDill.path, stdout: validConstFinderResult);
    resetFontSubsetInvocation(exitCode: -1, stdinSink: stdinSink);

    await expectLater(
      () => iconTreeShaker.subsetFont(
        input: fileSystem.file(inputPath),
        outputPath: outputPath,
        relativePath: relativePath,
      ),
      throwsA(isA<IconTreeShakerException>()),
    );
    expect(processManager, hasNoRemainingExpectations);
  });

  testWithoutContext('Invalid font manifest', () async {
    final Environment environment = createEnvironment(<String, String>{
      kIconTreeShakerFlag: 'true',
      kBuildMode: 'release',
    });
    final File appDill = environment.buildDir.childFile('app.dill')
      ..createSync(recursive: true);

    fontManifestContent = DevFSStringContent(invalidFontManifestJson);

    final IconTreeShaker iconTreeShaker = IconTreeShaker(
      environment,
      fontManifestContent,
      logger: logger,
      processManager: processManager,
      fileSystem: fileSystem,
      artifacts: artifacts,
      targetPlatform: TargetPlatform.android,
    );

    addConstFinderInvocation(appDill.path, stdout: validConstFinderResult);

    await expectLater(
      () => iconTreeShaker.subsetFont(
        input: fileSystem.file(inputPath),
        outputPath: outputPath,
        relativePath: relativePath,
      ),
      throwsA(isA<IconTreeShakerException>()),
    );
    expect(processManager, hasNoRemainingExpectations);
  });

  testWithoutContext('ConstFinder non-zero exit', () async {
    final Environment environment = createEnvironment(<String, String>{
      kIconTreeShakerFlag: 'true',
      kBuildMode: 'release',
    });
    final File appDill = environment.buildDir.childFile('app.dill')
      ..createSync(recursive: true);

    fontManifestContent = DevFSStringContent(invalidFontManifestJson);

    final IconTreeShaker iconTreeShaker = IconTreeShaker(
      environment,
      fontManifestContent,
      logger: logger,
      processManager: processManager,
      fileSystem: fileSystem,
      artifacts: artifacts,
      targetPlatform: TargetPlatform.android,
    );

    addConstFinderInvocation(appDill.path, exitCode: -1);

    await expectLater(
      () async => iconTreeShaker.subsetFont(
        input: fileSystem.file(inputPath),
        outputPath: outputPath,
        relativePath: relativePath,
      ),
      throwsA(isA<IconTreeShakerException>()),
    );
    expect(processManager, hasNoRemainingExpectations);
  });
}

const String validConstFinderResult = '''
{
  "constantInstances": [
    {
      "codePoint": 59470,
      "fontFamily": "MaterialIcons",
      "fontPackage": null,
      "matchTextDirection": false
    }
  ],
  "nonConstantLocations": []
}
''';

const String constFinderResultWithInvalid = '''
{
  "constantInstances": [
    {
      "codePoint": 59470,
      "fontFamily": "MaterialIcons",
      "fontPackage": null,
      "matchTextDirection": false
    }
  ],
  "nonConstantLocations": [
    {
      "file": "file:///Path/to/hello_world/lib/file.dart",
      "line": 19,
      "column": 11
    }
  ]
}
''';

const String validFontManifestJson = '''
[
  {
    "family": "MaterialIcons",
    "fonts": [
      {
        "asset": "fonts/MaterialIcons-Regular.otf"
      }
    ]
  },
  {
    "family": "GalleryIcons",
    "fonts": [
      {
        "asset": "packages/flutter_gallery_assets/fonts/private/gallery_icons/GalleryIcons.ttf"
      }
    ]
  },
  {
    "family": "packages/cupertino_icons/CupertinoIcons",
    "fonts": [
      {
        "asset": "packages/cupertino_icons/assets/CupertinoIcons.ttf"
      }
    ]
  }
]
''';

const String invalidFontManifestJson = '''
{
  "famly": "MaterialIcons",
  "fonts": [
    {
      "asset": "fonts/MaterialIcons-Regular.otf"
    }
  ]
}
''';
