// 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:html' as html;

import 'package:meta/dart2js.dart';

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';

// Tests that the framework prints stack traces in all build modes.
//
// Regression test for https://github.com/flutter/flutter/issues/68616.
//
// See also `dev/integration_tests/web/lib/stack_trace.dart` that tests the
// framework's ability to parse stack traces in all build modes.
void main() async {
  final StringBuffer errorMessage = StringBuffer();
  debugPrint = (String? message, { int? wrapWidth }) {
    errorMessage.writeln(message);
  };

  runApp(ThrowingWidget());

  // Let the framework flush error messages.
  await Future<void>.delayed(Duration.zero);

  final StringBuffer output = StringBuffer();
  if (_errorMessageFormattedCorrectly(errorMessage.toString())) {
    output.writeln('--- TEST SUCCEEDED ---');
  } else  {
    output.writeln('--- UNEXPECTED ERROR MESSAGE FORMAT ---');
    output.writeln(errorMessage);
    output.writeln('--- TEST FAILED ---');
  }

  print(output);
  html.HttpRequest.request(
    '/test-result',
    method: 'POST',
    sendData: '$output',
  );
}

bool _errorMessageFormattedCorrectly(String errorMessage) {
  if (!errorMessage.contains('Test error message')) {
    return false;
  }

  // In release mode symbols are minified. No sense testing the contents of the stack trace.
  if (kReleaseMode) {
    return true;
  }

  const List<String> expectedFunctions = <String>[
    'topLevelFunction',
    'secondLevelFunction',
    'thirdLevelFunction',
  ];

  return expectedFunctions.every(errorMessage.contains);
}

class ThrowingWidget extends StatefulWidget {
  @override
  _ThrowingWidgetState createState() => _ThrowingWidgetState();
}

class _ThrowingWidgetState extends State<ThrowingWidget> {
  @override
  void initState() {
    super.initState();
    topLevelFunction();
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

@noInline
void topLevelFunction() {
  secondLevelFunction();
}

@noInline
void secondLevelFunction() {
  thirdLevelFunction();
}

@noInline
void thirdLevelFunction() {
  throw Exception('Test error message');
}
