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

// Regression test for https://dartbug.com/53376.

import 'common/service_test_common.dart';
import 'common/test_helper.dart';

const String shortFile =
    'breakpoints_ignore_late_initialization_error_instructions_test.dart';

// AUTOGENERATED START
//
// Update these constants by running:
//
// dart pkg/vm_service/test/update_line_numbers.dart pkg/vm_service/test/breakpoints_ignore_late_initialization_error_instructions_test.dart
//
const LINE_A = 34;
const LINE_B = 44;
const LINE_C = 53;
// AUTOGENERATED END

int getThree() => 3;

void testeeMain() {
  // ignore: prefer_final_locals
  late int x = 1;
  final double xd =
      // When a late variable is read, the VM performs checks to ensure that the
      // variable has been initialized. When a breakpoint is set on the
      // following line, it should resolve to the [toDouble] call instruction,
      // not to an instruction part of the late variable initialization checks.
      x.toDouble(); // LINE_A
  print(xd);

  late final int y = 2;
  final double yd =
      // When a late final variable is read, the VM performs checks to ensure
      // that the variable has been assigned a value exactly once. When a
      // breakpoint is set on the following line, it should resolve to the
      // [toDouble] call instruction, not to an instruction part of the late
      // variable assignment checks.
      y.toDouble(); // LINE_B
  print(yd);

  late final int z;
  // When a late final variable is assigned a value, the VM performs checks to
  // ensure that the variable has not already been initialized. When a
  // breakpoint is set on the following line, it should resolve on the '='
  // token, not to an instruction part of the late variable initialization
  // checks.
  z = getThree(); // LINE_C
  print(z);
}

List<String> stops = [];

const List<String> expected = [
  '$shortFile:$LINE_A:9', // on 'toDouble'
  '$shortFile:$LINE_B:9', // on 'toDouble'
  '$shortFile:$LINE_C:7', // on 'getThree'
];

final tests = <IsolateTest>[
  hasPausedAtStart,
  setBreakpointAtLine(LINE_A),
  setBreakpointAtLine(LINE_B),
  setBreakpointAtLine(LINE_C),
  resumeProgramRecordingStops(stops, false),
  checkRecordedStops(stops, expected),
];

Future<void> main([args = const <String>[]]) => runIsolateTests(
      args,
      tests,
      shortFile,
      testeeConcurrent: testeeMain,
      pauseOnStart: true,
      pauseOnExit: true,
    );
