// Copyright (c) 2023, 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 'common/service_test_common.dart';
import 'common/test_helper.dart';

// AUTOGENERATED START
//
// Update these constants by running:
//
// dart pkg/vm_service/test/update_line_numbers.dart pkg/vm_service/test/step_through_function_test.dart
//
const LINE_A = 19;
// AUTOGENERATED END

const file = 'step_through_function_test.dart';

void code() /* LINE_A */ {
  final bar = Bar();
  print(bar.barXYZ1());
  print(bar.barXYZ2(4, 2));
  print(bar.barXYZ3());
  print(bar.barXYZ4(4, 2));
  print(fooXYZ1());
  print(fooXYZ2(4, 2));
  print(fooXYZ3());
  print(fooXYZ4(4, 2));
}

String fooXYZ1 /**/ () => 'fooXYZ';
String fooXYZ2 /**/ (int i, int j) => 'fooXYZ$i$j';
String fooXYZ3 /**/ () {
  return 'fooXYZ';
}

String fooXYZ4 /**/ (int i, int j) {
  return 'fooXYZ$i$j';
}

class Bar {
  String barXYZ1 /**/ () => 'barXYZ';
  String barXYZ2 /**/ (int i, int j) => 'barXYZ$i$j';
  String barXYZ3 /**/ () {
    return 'barXYZ';
  }

  String barXYZ4 /**/ (int i, int j) {
    return 'barXYZ$i$j';
  }
}

final stops = <String>[];
const expected = <String>[
  '$file:${LINE_A + 0}:10', // after 'code'
  '$file:${LINE_A + 1}:15', // on 'Bar'

  '$file:${LINE_A + 2}:13', // on 'barXYZ1'
  '$file:${LINE_A + 23}:23', // after 'barXYZ1', i.e. on '('
  '$file:${LINE_A + 23}:29', // on first '''
  '$file:${LINE_A + 2}:3', // on 'print'

  '$file:${LINE_A + 3}:13', // on 'barXYZ2'
  '$file:${LINE_A + 24}:35', // on 'j'
  '$file:${LINE_A + 24}:53', // after last ''', i.e. on ';'
  '$file:${LINE_A + 24}:41', // on first '''
  '$file:${LINE_A + 3}:3', // on 'print'

  '$file:${LINE_A + 4}:13', // on 'barXYZ3'
  '$file:${LINE_A + 25}:23', // after 'barXYZ3', i.e. on '('
  '$file:${LINE_A + 26}:5', // on 'return'
  '$file:${LINE_A + 4}:3', // on 'print'

  '$file:${LINE_A + 5}:13', // on 'barXYZ4'
  '$file:${LINE_A + 29}:35', // on 'j'
  '$file:${LINE_A + 30}:24', // after last ''', i.e. on ';'
  '$file:${LINE_A + 30}:5', // on 'return'
  '$file:${LINE_A + 5}:3', // on 'print'

  '$file:${LINE_A + 6}:9', // on 'fooXYZ1'
  '$file:${LINE_A + 12}:21', // after 'fooXYZ1', i.e. on '('
  '$file:${LINE_A + 12}:27', // on first '''
  '$file:${LINE_A + 6}:3', // on 'print'

  '$file:${LINE_A + 7}:9', // on 'fooXYZ2'
  '$file:${LINE_A + 13}:33', // on 'j'
  '$file:${LINE_A + 13}:51', // after last ''', i.e. on ';'
  '$file:${LINE_A + 13}:39', // on first '''
  '$file:${LINE_A + 7}:3', // on 'print'

  '$file:${LINE_A + 8}:9', // on 'fooXYZ3'
  '$file:${LINE_A + 14}:21', // after 'fooXYZ3', i.e. on '('
  '$file:${LINE_A + 15}:3', // on 'return'
  '$file:${LINE_A + 8}:3', // on 'print'

  '$file:${LINE_A + 9}:9', // on 'fooXYZ4'
  '$file:${LINE_A + 18}:33', // on 'j'
  '$file:${LINE_A + 19}:22', // after last ''', i.e. on ';'
  '$file:${LINE_A + 19}:3', // on 'return'
  '$file:${LINE_A + 9}:3', // on 'print'

  '$file:${LINE_A + 10}:1', // on ending '}'
];

final tests = <IsolateTest>[
  hasPausedAtStart,
  setBreakpointAtLine(LINE_A),
  runStepIntoThroughProgramRecordingStops(stops),
  checkRecordedStops(
    stops,
    expected,
    debugPrint: true,
    debugPrintFile: file,
    debugPrintLine: LINE_A,
  ),
];

void main([args = const <String>[]]) => runIsolateTests(
      args,
      tests,
      'step_through_function_test.dart',
      testeeConcurrent: code,
      pauseOnStart: true,
      pauseOnExit: true,
    );
