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

// ignore_for_file: avoid_dynamic_calls

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

import 'package:collection/collection.dart';
import 'package:kernel/const_finder.dart';
import 'package:path/path.dart' as path;

void expect<T>(T value, T expected) {
  if (value != expected) {
    stderr.writeln('Expected: $expected');
    stderr.writeln('Actual:   $value');
    exitCode = -1;
  }
}

void expectInstances(dynamic value, dynamic expected, Compiler compiler) {
  // To ensure we ignore insertion order into maps as well as lists we use
  // DeepCollectionEquality as well as sort the lists.

  int compareByStringValue(dynamic a, dynamic b) {
    return a['stringValue'].compareTo(b['stringValue']) as int;
  }
  value['constantInstances'].sort(compareByStringValue);
  expected['constantInstances'].sort(compareByStringValue);

  final Equality<Object?> equality;
  if (compiler == Compiler.dart2js) {
    equality = const Dart2JSDeepCollectionEquality();
  } else {
    equality = const DeepCollectionEquality();
  }
  if (!equality.equals(value, expected)) {
    stderr.writeln('Expected: ${jsonEncode(expected)}');
    stderr.writeln('Actual:   ${jsonEncode(value)}');
    exitCode = -1;
  }
}

// This test is assuming the `dart` used to invoke the tests is compatible
// with the version of package:kernel in //third-party/dart/pkg/kernel
final String dart = Platform.resolvedExecutable;
final String dartaotruntime = path.join(path.dirname(Platform.resolvedExecutable), 'dartaotruntime');

void _checkRecursion(String dillPath, Compiler compiler) {
  stdout.writeln('Checking recursive calls.');
  final ConstFinder finder = ConstFinder(
    kernelFilePath: dillPath,
    classLibraryUri: 'package:const_finder_fixtures/box.dart',
    className: 'Box',
  );
  // Will timeout if we did things wrong.
  jsonEncode(finder.findInstances());
}

void _checkConsts(String dillPath, Compiler compiler) {
  stdout.writeln('Checking for expected constants.');
  final ConstFinder finder = ConstFinder(
    kernelFilePath: dillPath,
    classLibraryUri: 'package:const_finder_fixtures/target.dart',
    className: 'Target',
  );
  final Map<String, Object?> expectation = <String, dynamic>{
      'constantInstances': <Map<String, dynamic>>[
        <String, dynamic>{'stringValue': '100', 'intValue': 100, 'targetValue': null},
        <String, dynamic>{'stringValue': '102', 'intValue': 102, 'targetValue': null},
        <String, dynamic>{'stringValue': '101', 'intValue': 101},
        <String, dynamic>{'stringValue': '103', 'intValue': 103, 'targetValue': null},
        <String, dynamic>{'stringValue': '105', 'intValue': 105, 'targetValue': null},
        <String, dynamic>{'stringValue': '104', 'intValue': 104},
        <String, dynamic>{'stringValue': '106', 'intValue': 106, 'targetValue': null},
        <String, dynamic>{'stringValue': '108', 'intValue': 108, 'targetValue': null},
        <String, dynamic>{'stringValue': '107', 'intValue': 107},
        <String, dynamic>{'stringValue': '1', 'intValue': 1, 'targetValue': null},
        <String, dynamic>{'stringValue': '4', 'intValue': 4, 'targetValue': null},
        <String, dynamic>{'stringValue': '2', 'intValue': 2},
        <String, dynamic>{'stringValue': '6', 'intValue': 6, 'targetValue': null},
        <String, dynamic>{'stringValue': '8', 'intValue': 8, 'targetValue': null},
        <String, dynamic>{'stringValue': '10', 'intValue': 10, 'targetValue': null},
        <String, dynamic>{'stringValue': '9', 'intValue': 9},
        <String, dynamic>{'stringValue': '7', 'intValue': 7, 'targetValue': null},
        <String, dynamic>{'stringValue': '11', 'intValue': 11, 'targetValue': null},
        <String, dynamic>{'stringValue': '12', 'intValue': 12, 'targetValue': null},
        <String, dynamic>{'stringValue': 'package', 'intValue':-1, 'targetValue': null},
      ],
      'nonConstantLocations': <dynamic>[],
    };
  if (compiler == Compiler.aot) {
    expectation['nonConstantLocations'] = <Object?>[];
  } else {
    final String fixturesUrl = Platform.isWindows
      ? '/$fixtures'.replaceAll(Platform.pathSeparator, '/')
      : fixtures;

    // Without true tree-shaking, there is a non-const reference in a
    // never-invoked function that will be present in the dill.
    expectation['nonConstantLocations'] = <Object?>[
      <String, dynamic>{
        'file': 'file://$fixturesUrl/pkg/package.dart',
        'line': 14,
        'column': 25,
      },
    ];
  }
  expectInstances(
    finder.findInstances(),
    expectation,
    compiler,
  );

  final ConstFinder finder2 = ConstFinder(
    kernelFilePath: dillPath,
    classLibraryUri: 'package:const_finder_fixtures/target.dart',
    className: 'MixedInTarget',
  );
  expectInstances(
    finder2.findInstances(),
    <String, dynamic>{
      'constantInstances': <Map<String, dynamic>>[
        <String, dynamic>{'val': '13'},
      ],
      'nonConstantLocations': <dynamic>[],
    },
    compiler,
  );
}

void _checkAnnotation(String dillPath, Compiler compiler) {
  stdout.writeln('Checking constant instances in a class annotated with instance of StaticIconProvider are ignored with $compiler');
  final ConstFinder finder = ConstFinder(
    kernelFilePath: dillPath,
    classLibraryUri: 'package:const_finder_fixtures/target.dart',
    className: 'Target',
    annotationClassName: 'StaticIconProvider',
    annotationClassLibraryUri: 'package:const_finder_fixtures/static_icon_provider.dart',
  );
  final Map<String, dynamic> instances = finder.findInstances();
  expectInstances(
    instances,
    <String, dynamic>{
      'constantInstances': <Map<String, Object?>>[
        <String, Object?>{
          'stringValue': 'used1',
          'intValue': 1,
          'targetValue': null,
        },
        <String, Object?>{
          'stringValue': 'used2',
          'intValue': 2,
          'targetValue': null,
        },
      ],
      // TODO(fujino): This should have non-constant locations from the use of
      // a tear-off, see https://github.com/flutter/flutter/issues/116797
      'nonConstantLocations': <Object?>[],
    },
    compiler,
  );
}

void _checkNonConstsFrontend(String dillPath, Compiler compiler) {
  stdout.writeln('Checking for non-constant instances with $compiler');
  final ConstFinder finder = ConstFinder(
    kernelFilePath: dillPath,
    classLibraryUri: 'package:const_finder_fixtures/target.dart',
    className: 'Target',
  );
  final String fixturesUrl = Platform.isWindows
    ? '/$fixtures'.replaceAll(Platform.pathSeparator, '/')
    : fixtures;

  expectInstances(
    finder.findInstances(),
    <String, dynamic>{
      'constantInstances': <dynamic>[
        <String, dynamic>{'stringValue': '1', 'intValue': 1, 'targetValue': null},
        <String, dynamic>{'stringValue': '4', 'intValue': 4, 'targetValue': null},
        <String, dynamic>{'stringValue': '6', 'intValue': 6, 'targetValue': null},
        <String, dynamic>{'stringValue': '8', 'intValue': 8, 'targetValue': null},
        <String, dynamic>{'stringValue': '10', 'intValue': 10, 'targetValue': null},
        <String, dynamic>{'stringValue': '9', 'intValue': 9},
        <String, dynamic>{'stringValue': '7', 'intValue': 7, 'targetValue': null},
      ],
      'nonConstantLocations': <dynamic>[
        <String, dynamic>{
          'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
          'line': 14,
          'column': 26,
        },
        <String, dynamic>{
          'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
          'line': 16,
          'column': 26,
        },
        <String, dynamic>{
          'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
          'line': 16,
          'column': 41,
        },
        <String, dynamic>{
          'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
          'line': 17,
          'column': 26,
        },
        <String, dynamic>{
          'file': 'file://$fixturesUrl/pkg/package.dart',
          'line': 14,
          'column': 25,
        }
      ]
    },
    compiler,
  );
}

// Note, since web dills don't have tree shaking, we aren't able to eliminate
// an additional const versus _checkNonConstFrontend.
void _checkNonConstsWeb(String dillPath, Compiler compiler) {
  assert(compiler == Compiler.dart2js);
  stdout.writeln('Checking for non-constant instances with $compiler');
  final ConstFinder finder = ConstFinder(
    kernelFilePath: dillPath,
    classLibraryUri: 'package:const_finder_fixtures/target.dart',
    className: 'Target',
  );

  final String fixturesUrl = Platform.isWindows
    ? '/$fixtures'.replaceAll(Platform.pathSeparator, '/')
    : fixtures;
  expectInstances(
    finder.findInstances(),
    <String, dynamic>{
      'constantInstances': <dynamic>[
        <String, dynamic>{'stringValue': '1', 'intValue': 1, 'targetValue': null},
        <String, dynamic>{'stringValue': '4', 'intValue': 4, 'targetValue': null},
        <String, dynamic>{'stringValue': '6', 'intValue': 6, 'targetValue': null},
        <String, dynamic>{'stringValue': '8', 'intValue': 8, 'targetValue': null},
        <String, dynamic>{'stringValue': '10', 'intValue': 10, 'targetValue': null},
        <String, dynamic>{'stringValue': '9', 'intValue': 9},
        <String, dynamic>{'stringValue': '7', 'intValue': 7, 'targetValue': null},
        <String, dynamic>{'stringValue': 'package', 'intValue': -1, 'targetValue': null},
      ],
      'nonConstantLocations': <dynamic>[
        <String, dynamic>{
          'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
          'line': 14,
          'column': 26,
        },
        <String, dynamic>{
          'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
          'line': 16,
          'column': 26,
        },
        <String, dynamic>{
          'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
          'line': 16,
          'column': 41,
        },
        <String, dynamic>{
          'file': 'file://$fixturesUrl/lib/consts_and_non.dart',
          'line': 17,
          'column': 26,
        },
        <String, dynamic>{
          'file': 'file://$fixturesUrl/pkg/package.dart',
          'line': 14,
          'column': 25,
        }
      ],
    },
    compiler,
  );
}

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

final String basePath =
    path.canonicalize(path.join(path.dirname(Platform.script.toFilePath()), '..'));
final String fixtures = path.join(basePath, 'test', 'fixtures');
final String packageConfig = path.join(fixtures, '.dart_tool', 'package_config.json');

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

  final String frontendServer = args[0];
  final String sdkRoot = args[1];
  final String librariesSpec = args[2];

  final List<_Test> tests = <_Test>[
    _Test(
      name: 'box_frontend',
      dartSource: path.join(fixtures, 'lib', 'box.dart'),
      frontendServer: frontendServer,
      sdkRoot: sdkRoot,
      librariesSpec: librariesSpec,
      verify: _checkRecursion,
      compiler: Compiler.aot,
    ),
    _Test(
      name: 'box_web',
      dartSource: path.join(fixtures, 'lib', 'box.dart'),
      frontendServer: frontendServer,
      sdkRoot: sdkRoot,
      librariesSpec: librariesSpec,
      verify: _checkRecursion,
      compiler: Compiler.dart2js,
    ),
    _Test(
      name: 'consts_frontend',
      dartSource: path.join(fixtures, 'lib', 'consts.dart'),
      frontendServer: frontendServer,
      sdkRoot: sdkRoot,
      librariesSpec: librariesSpec,
      verify: _checkConsts,
      compiler: Compiler.aot,
    ),
    _Test(
      name: 'consts_web',
      dartSource: path.join(fixtures, 'lib', 'consts.dart'),
      frontendServer: frontendServer,
      sdkRoot: sdkRoot,
      librariesSpec: librariesSpec,
      verify: _checkConsts,
      compiler: Compiler.dart2js,
    ),
    _Test(
      name: 'consts_and_non_frontend',
      dartSource: path.join(fixtures, 'lib', 'consts_and_non.dart'),
      frontendServer: frontendServer,
      sdkRoot: sdkRoot,
      librariesSpec: librariesSpec,
      verify: _checkNonConstsFrontend,
      compiler: Compiler.aot,
    ),
    _Test(
      name: 'consts_and_non_web',
      dartSource: path.join(fixtures, 'lib', 'consts_and_non.dart'),
      frontendServer: frontendServer,
      sdkRoot: sdkRoot,
      librariesSpec: librariesSpec,
      verify: _checkNonConstsWeb,
      compiler: Compiler.dart2js,
    ),
    _Test(
      name: 'static_icon_provider_frontend',
      dartSource: path.join(fixtures, 'lib', 'static_icon_provider.dart'),
      frontendServer: frontendServer,
      sdkRoot: sdkRoot,
      librariesSpec: librariesSpec,
      verify: _checkAnnotation,
      compiler: Compiler.aot,
    ),
    _Test(
      name: 'static_icon_provider_web',
      dartSource: path.join(fixtures, 'lib', 'static_icon_provider.dart'),
      frontendServer: frontendServer,
      sdkRoot: sdkRoot,
      librariesSpec: librariesSpec,
      verify: _checkAnnotation,
      compiler: Compiler.dart2js,
    ),
  ];
  try {
    stdout.writeln('Generating kernel fixtures...');

    for (final _Test test in tests) {
      test.run();
    }
  } finally {
    try {
      for (final _Test test in tests) {
        test.dispose();
      }
    } finally {
      stdout.writeln('Tests ${exitCode == 0 ? 'succeeded' : 'failed'} - exit code: $exitCode');
    }
  }
}

enum Compiler {
  // Uses TFA tree-shaking.
  aot,
  // Does not have TFA tree-shaking.
  dart2js,
}

class _Test {
  _Test({
    required this.name,
    required this.dartSource,
    required this.sdkRoot,
    required this.verify,
    required this.frontendServer,
    required this.librariesSpec,
    required this.compiler,
  }) : dillPath = path.join(fixtures, '$name.dill');

  final String name;
  final String dartSource;
  final String sdkRoot;
  final String frontendServer;
  final String librariesSpec;
  final String dillPath;
  void Function(String, Compiler) verify;
  final Compiler compiler;

  final List<String> resourcesToDispose = <String>[];

  void run() {
    stdout.writeln('Compiling $dartSource to $dillPath with $compiler');

    if (compiler == Compiler.aot) {
      _compileAOTDill();
    } else {
      _compileWebDill();
    }

    stdout.writeln('Testing $dillPath');

    verify(dillPath, compiler);
  }

  void dispose() {
    for (final String resource in resourcesToDispose) {
      stdout.writeln('Deleting $resource');
      File(resource).deleteSync();
    }
  }

  void _compileAOTDill() {
    checkProcessResult(Process.runSync(dartaotruntime, <String>[
      frontendServer,
      '--sdk-root=$sdkRoot',
      '--target=flutter',
      '--aot',
      '--tfa',
      '--packages=$packageConfig',
      '--output-dill=$dillPath',
      dartSource,
    ]));

    resourcesToDispose.add(dillPath);
  }

  void _compileWebDill() {
    final ProcessResult result = Process.runSync(dart, <String>[
      'compile',
      'js',
      '--libraries-spec=$librariesSpec',
      '-Ddart.vm.product=true',
      '-o',
      dillPath,
      '--packages=$packageConfig',
      '--cfe-only',
      dartSource,
    ]);
    checkProcessResult(result);

    resourcesToDispose.add(dillPath);
  }
}

/// Equality that casts all [num]'s to [double] before comparing.
class Dart2JSDeepCollectionEquality extends DeepCollectionEquality {
  const Dart2JSDeepCollectionEquality();

  @override
  bool equals(Object? e1, Object? e2) {
    if (e1 is num && e2 is num) {
      return e1.toDouble() == e2.toDouble();
    }
    return super.equals(e1, e2);
  }
}
