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

import 'dart:io';

import 'package:file/file.dart';

import '../src/common.dart';
import 'test_data/stepping_project.dart';
import 'test_driver.dart';
import 'test_utils.dart';

void main() {
  testWithoutContext('can step over statements', () async {
    final Directory tempDir = createResolvedTempDirectorySync('debugger_stepping_test.');

    final SteppingProject _project = SteppingProject();
    await _project.setUpIn(tempDir);

    final FlutterRunTestDriver _flutter = FlutterRunTestDriver(tempDir);

    await _flutter.run(withDebugger: true, startPaused: true);
    await _flutter.addBreakpoint(_project.breakpointUri, _project.breakpointLine);
    await _flutter.resume();
    await _flutter.waitForPause(); // Now we should be on the breakpoint.

    expect((await _flutter.getSourceLocation()).line, equals(_project.breakpointLine));

    // Issue 5 steps, ensuring that we end up on the annotated lines each time.
    for (int i = 1; i <= _project.numberOfSteps; i += 1) {
      await _flutter.stepOverOrOverAsyncSuspension();
      final SourcePosition location = await _flutter.getSourceLocation();
      final int actualLine = location.line;

      // Get the line we're expected to stop at by searching for the comment
      // within the source code.
      final int expectedLine = _project.lineForStep(i);

      expect(actualLine, equals(expectedLine),
        reason: 'After $i steps, debugger should stop at $expectedLine but stopped at $actualLine'
      );
    }

    await _flutter.stop();
    tryToDelete(tempDir);
  });
}
