// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
// for details. 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:async_helper/async_helper.dart';
import 'package:compiler/src/closure.dart';
import 'package:compiler/src/common.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/js_model/element_map.dart';
import 'package:compiler/src/js_model/js_strategy.dart';
import 'package:compiler/src/js_model/js_world.dart';
import 'package:kernel/ast.dart' as ir;
import '../equivalence/id_equivalence.dart';
import '../equivalence/id_equivalence_helper.dart';

const List<String> skip = [];
const List<String> skip2 = [];

main(List<String> args) {
  runTests(args);
  runTests2(args);
}

runTests(List<String> args, [int? shardIndex]) {
  runTestsCommon(args,
      shardIndex: shardIndex,
      shards: 2,
      directory: 'data',
      skip: skip,
      options: [Flags.soundNullSafety]);
}

runTests2(List<String> args, [int? shardIndex]) {
  runTestsCommon(args,
      shardIndex: shardIndex,
      shards: 2,
      directory: 'data_2',
      skip: skip2,
      options: []);
}

runTestsCommon(List<String> args,
    {int? shardIndex,
    required int shards,
    required String directory,
    required List<String> options,
    required List<String> skip}) {
  asyncTest(() async {
    Directory dataDir = Directory.fromUri(Platform.script.resolve(directory));
    await checkTests(dataDir, const CodegenDataComputer(),
        forUserLibrariesOnly: true,
        args: args,
        options: options,
        testedConfigs: allInternalConfigs + [canaryConfig],
        skip: skip,
        shardIndex: shardIndex ?? 0,
        shards: shardIndex == null ? 1 : shards);
  });
}

class CodegenDataComputer extends DataComputer<String> {
  const CodegenDataComputer();

  /// Compute generated code for [member].
  ///
  /// Fills [actualMap] with the data.
  @override
  void computeMemberData(Compiler compiler, MemberEntity member,
      Map<Id, ActualData<String>> actualMap,
      {bool verbose = false}) {
    JClosedWorld closedWorld = compiler.backendClosedWorldForTesting!;
    JsToElementMap elementMap = closedWorld.elementMap;
    MemberDefinition definition = elementMap.getMemberDefinition(member);
    CodegenIrComputer(compiler.reporter, actualMap, elementMap, member,
            compiler.backendStrategy, closedWorld.closureDataLookup)
        .run(definition.node);
  }

  @override
  DataInterpreter<String> get dataValidator => const CodeDataInterpreter();
}

/// AST visitor for computing codegen data for a member.
class CodegenIrComputer extends IrDataExtractor<String> {
  final JsBackendStrategy _backendStrategy;
  final JsToElementMap _elementMap;
  final ClosureData _closureDataLookup;

  CodegenIrComputer(
      DiagnosticReporter reporter,
      Map<Id, ActualData<String>> actualMap,
      this._elementMap,
      MemberEntity member,
      this._backendStrategy,
      this._closureDataLookup)
      : super(reporter, actualMap);

  String? getMemberValue(MemberEntity member) {
    if (member is FunctionEntity) {
      return _backendStrategy.getGeneratedCodeForTesting(member);
    }
    return null;
  }

  @override
  String? computeMemberValue(Id id, ir.Member node) {
    return getMemberValue(_elementMap.getMember(node));
  }

  @override
  String? computeNodeValue(Id id, ir.TreeNode node) {
    if (node is ir.FunctionExpression || node is ir.FunctionDeclaration) {
      ClosureRepresentationInfo info =
          _closureDataLookup.getClosureInfo(node as ir.LocalFunction);
      return getMemberValue(info.callMethod!);
    }
    return null;
  }
}

/// Default data interpreter for string data representing compiled JavaScript
/// code.
///
/// The data annotation reader strips out newlines and indentation so the
/// comparison needs to compensate.
///
/// The special data annotation `ignore` always passes, so we don't have to
/// track uninteresting code like a 'main' program.
class CodeDataInterpreter implements DataInterpreter<String> {
  const CodeDataInterpreter();

  String _clean(String code) => code.replaceAll(_re, '');
  static final RegExp _re = RegExp(r'[\n\r]\s*');

  @override
  String? isAsExpected(String? actualData, String? expectedData) {
    actualData ??= '';
    expectedData ??= '';
    if (expectedData == 'ignore') return null;
    if (_clean(actualData) != _clean(expectedData)) {
      return 'Expected $expectedData, found $actualData';
    }
    return null;
  }

  @override
  bool isEmpty(String actualData) {
    return _clean(actualData) == '';
  }

  @override
  String getText(String actualData, [String? indentation]) {
    return actualData;
  }
}
