// Copyright (c) 2018, 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.

// Test that `length` access in JSArray.indexOf is encoding using `.length` and
// not `.get$length()`.

import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/names.dart';
import 'package:compiler/src/js_model/js_world.dart';
import 'package:compiler/src/js_emitter/model.dart';
import 'package:compiler/src/js_model/js_strategy.dart';
import 'package:compiler/src/js/js.dart' as js;
import 'package:compiler/src/universe/selector.dart';
import 'package:expect/async_helper.dart';
import 'package:expect/expect.dart';
import 'package:compiler/src/util/memory_compiler.dart';
import '../helpers/element_lookup.dart';
import '../helpers/program_lookup.dart';

const String source = '''
import 'package:expect/expect.dart';

@pragma('dart2js:noInline')
test(o, a) => o.indexOf(a);
main() {
  test([1, 2, 3], 2);
  test(['1', '2', '3'], '2');
}
''';

main() {
  asyncTest(() async {
    print('--test from kernel (strong mode)----------------------------------');
    await runTest([]);
    print('--test from kernel (strong mode, omit-implicit-checks)------------');
    await runTest([Flags.omitImplicitChecks]);
  });
}

runTest(List<String> options) async {
  CompilationResult result = await runCompiler(
    memorySourceFiles: {'main.dart': source},
    options: options,
  );
  Expect.isTrue(result.isSuccess);
  Compiler compiler = result.compiler!;
  JsBackendStrategy backendStrategy = compiler.backendStrategy;
  JClosedWorld closedWorld = compiler.backendClosedWorldForTesting!;
  final jsArrayIndexOf =
      findClassMember(closedWorld, 'JSArray', 'indexOf') as FunctionEntity;
  ProgramLookup programLookup = ProgramLookup(backendStrategy);

  Selector getLengthSelector = Selector.getter(const PublicName('length'));
  js.Name getLengthName = backendStrategy.namerForTesting.invocationName(
    getLengthSelector,
  );

  Method method = programLookup.getMethod(jsArrayIndexOf)!;
  int lengthCount = 0;
  forEachNode(
    method.code,
    onCall: (js.Call node) {
      js.Node target = node.target;
      Expect.isFalse(
        target is js.PropertyAccess && target.selector == getLengthName,
        "Unexpected .get\$length access ${js.nodeToString(node)} in\n"
        "${js.nodeToString(method.code, pretty: true)}",
      );
    },
    onPropertyAccess: (js.PropertyAccess node) {
      js.Node selector = node.selector;
      if (selector is js.LiteralString && selector.value == 'length') {
        lengthCount++;
      }
    },
  );
  Expect.equals(
    2,
    lengthCount,
    "Unexpected .length access in\n"
    "${js.nodeToString(method.code, pretty: true)}",
  );
}
